【问题标题】:Is there a statically weak typed language?是否存在静态弱类型语言?
【发布时间】:2012-12-12 08:17:42
【问题描述】:

我一直在阅读

  • 静态(在编译时检查类型)和
  • 动态(在运行时检查类型)类型

对比

  • strong(无隐式转换)和
  • (隐式转换)类型

我知道它们是不同的东西(也讨论过here),所以我一直在以这种方式考虑示例语言:

  • 静态 - (C、C++、Java、..)
  • 静态 - (???)
  • 动态 - strong (python, ruby​​, ..)
  • 动态 - (perl, javascript, ..)

所以我的问题是,那里有没有静态弱类型语言? (我想如果不是没有的话,这样做也没什么意义)。我的理解/上面的例子也正确吗?

【问题讨论】:

  • C 可能被认为是一种具有弱类型的静态类型语言,因为它的 void * 和松散的类型转换。但这不是一个很好的例子,我知道。
  • @EarlGray Good 认为您提出了它,因为链接问题中的第二个答案认为同样的事情。尽管您可以将多种类型相互转换,但您通常需要明确说明它,所以我不太明白如何将 C 视为一种弱类型语言。
  • 我怀疑 C/C++/Java 中的原始类型应该被称为强类型。 int xx = 1; char yy = 'b'; float zz = xx + yy; 不是在所有这三种语言中都完全有效吗?如果一种语言中存在弱类型的类型,那么这会使您的整个语言成为弱类型。
  • @Tinctorius 我明白你的意思。如果您仅考虑原语,它们是弱类型语言,但如果您考虑 string(不包括 C),事情就会与 perl 或 javascript 等其他弱语言不同(例如,不能将 string 添加到 int)。此外,据我所知,甚至没有在 perl 中进行显式转换的选项,因此我认为将其视为一种弱语言是公平的,而 C 系列会比 perl 更强大,但不如 haskell 之类的强大。跨度>
  • 正如您已经注意到的,这在很大程度上取决于您对弱类型的定义。几乎所有涉及该术语的其他问题都相同。这就是我讨厌这个词的原因。我相信我们应该abandon the term "weak typing" entirely。如果您真的特别关心隐式转换,那么您可以通过删除该术语的所有用法来解决这个问题,而只谈论隐式转换。

标签: types casting programming-languages


【解决方案1】:

C# 允许用户定义的隐式转换,因此它符合您对“静态”和“弱”的定义(尽管“弱点”是有界的)。

【讨论】:

  • 这不是弱类型语言的原因。 C# 是非常强类型的语言。 OP的话不太准确
  • @nawfal - “弱”和“强”的定义并没有得到普遍认同,我选择的是 OP 使用的定义。如果 C# 是“非常强类型”,那么 F# 是“非常非常强类型”而 Haskell 是“非常、非常、非常强类型”?此外,谈论定义的“准确性”是没有意义的,人们可以对事物做出自己的定义(我们在数学中一直这样做),但由你决定是否不是定义有用。
  • 我猜你会进入这个 :) 无论如何,你最后的评论是一个更有用的答案。我没有投票给它错误的答案(在相对点上没有绝对错误),而是因为答案很差,不完整。如果强弱的整点是有争议的,那么它值得一提。更重要的是,当您正在谈论的非常隐式转换已经是 C++ 和 Java 的一个特性时,OP 已经包含在强类型语言中,这使得进一步提到像 C# 这样的类似语言毫无意义。
  • 我的意思是你的答案需要更多解释,不是因为它不完整,而是因为否则它可能会完全误导。就我个人而言,我没有得到这整个非通用定义的潮流。当有人说它相对于技术纯度时,我可以理解,但是语言可以被归类为强类型或弱类型有一定的限制。 php、perl 等语言的基本性质与 c#、java 等语言不同。
  • @nawfal - 强/弱二分法并不是有争议的,而是它依赖于上下文。 C# 类型系统比 F# 类型系统“弱”,例如,如果 IT 实现的接口,它允许从类型 T 到类型 I 的隐式转换。因此,说一种语言是弱类型的就像说汽车行驶缓慢,因为它们必须在停车标志处停下来,而飞机则不需要。
【解决方案2】:

强类型和弱类型的定义没有很好的定义,尤其是在只评价一种语言的情况下。它是比较语言的常用轴,在这种情况下,强类型和弱类型获得更多意义,但重要的是要理解没有像静态和动态这样的严格定义。使类型系统变弱或变强的原因归结为程序员能够创建类型错误的方式。

未经检查的显式转换

很多人会认为 C 是弱类型的,因为程序员可以转换类型。如果我只是告诉 C 它们都是整数,我可以添加一个指向字符的指针。

int main () {
    char c = 'a';
    void *p;
    (int)c + (int)p;
}

然而,在 Haskell 中,我可以显式地将一种类型转换为另一种类型,但只有某些类型可以工作。

ord('c') + 10
fromIntegral (2::Int) + 4.13

Java 也有静态类型转换,例如,它允许程序员向下转换对象。这使得静态类型系统不健全。但是 Java 正是出于这个原因而具有动态类型检查。是的,Java 有动态和静态类型检查。然而,出于这个原因,我想很多人会认为 Java 是强类型的。

自动投射

Perl 和 Javascript 将接受字符串并将其视为数字,如果它们看起来足够像数字并自动使其工作。

'2 is my favorite number' + 413 == 415 # in Perl

如果你想将一个字符串转换为一个数字,比如说,Scheme,你必须使用一个函数进行显式转换,如果字符串不是数字,则该函数会进行检查并引发异常。

(= (+ (string->number '2') 413) 415) ; In Scheme

出于这个原因,很多人会认为 Scheme 是强类型的。

根本没有类型

在某些语言中没有任何类型。无类型的 Lambda 演算就是这样一个例子。这显然不是强类型的。一切都是函数。我可以使用教堂数字或对或字符串或任何使用各种编码的数字来获取数字,但值仅表示我同意它们的含义,并且肯定存在重叠。

比较

就像我说的那样,这些术语没有很好的定义,但是当以相对的方式使用时它们会更有用一些。例如,我可以很好地声称 OCaml 的类型比 Java 更强,因为 Java 允许显式静态向下转换,而 OCaml 则不允许。

结论

这些术语并不严格,但它们很有用。为了回答您最初的问题,我认为 C/C++ 是静态且弱类型的,因此它们符合描述。

【讨论】:

  • because Java allows for explicit static down casting whereas OCaml does not 我怀疑这个说法。 OCaml 也可以在floatint(例如)之间进行转换,只是它通过函数int_of_floatfloat_of_int 执行,而不像(int)1.2。但是如果你认为(int)bit 是Java 内部的一个静态方法,那也是一样的。我相信你错过了使用explicit,它实际上应该是implicit。例如,在java中你可以做1.5 + 1,里面的1被隐式转换为float,但在OCaml中,你不能这样做。 OCaml 中没有隐式类型转换,因此更强大。
  • 这是真的。 OCaml 不允许向下转换,而 Java 允许。这里的区别在于您在 OCaml 中描述的 int_of_float 不是向下转换。这是从一种类型到另一种类型的转换。这根本不是演员表。在 Java 中从 int 转换为 float 也不是。向下转换是子类型之间的一种操作,对象相互继承。我可以将圆视为 OCaml 和 Java 中的形状。但只有在 Java 中,我才能说:“嘿,这个形状……它是一个圆圈,相信我。”它会静态工作,但如果你不正确,它会在运行时被 Java 的动态类型检查器捕获。
猜你喜欢
  • 2014-02-03
  • 2011-02-03
  • 2013-02-03
  • 1970-01-01
  • 2011-02-18
  • 1970-01-01
  • 1970-01-01
  • 2010-12-05
  • 2023-03-11
相关资源
最近更新 更多