万里旅行网

弱类型、强类型、动态类型、静态类型语言的区别是什么?

来源:www.wlogo.net   时间:2023-03-31 16:45   点击:290  编辑:yyns   手机版

前面 @姚培森 给的定义比较详细,但我觉得并不易于理解,而且我看到评论里已经有人产生了一些误解。我的理解是,这些概念本身就只是一种通俗的说法,并没有严格的定义,只能勉强用一些术语来厘清边界。下面是《Programming Language:Application and Interpretation》里给的一种解释,我觉得更易于理解:

从图上看,静态类型、动态类型大家应该明白其实是指的Type Check发生的时机。而强类型、弱类型到底是什么意思呢?其实这些词语本身概念就是模糊不清的,反正我是能避免使用就尽量避免使用。So what is “strong typing”?

This appears to be a meaningless phrase, and people often use it in a non-sensical fashion. To some it seems to mean “The language has a type checker”. To others it means “The language is sound” (that is, the type checker and run-time system are related). To most, it seems to just
mean, “A language like Pascal, C or Java, related in a way I can’t quite make precise”. If someone uses this
phrase, be sure to ask them to define it for you. (For amusement, watch them squirm.)

@刘典@姚培森 的回答下面提了一个疑问,我理了一下这个逻辑:

  • 按照定义,如果在编译时拒绝ill behaved程序,则是statically typed。
  • 按照定义,如果一种语言的所有程序都是well behaved,则该语言为strongly typed。
  • 那么,所有statically typed语言都是well behaved,即strongly typed。

这逻辑错在哪里呢?问题在于:在编译时拒绝(部分)ill behaved是编译器的行为,并不是概念上的定义。事实上,问题正出在 「Statically Typed」这个词身上!

可以这么说,并不存在 Statically Typed,只有 Statically Checked。

http://lucacardelli.name/papers/typesystems.pdf

In general, we avoid the words type and typing when referring to run time concepts; for example we replace dynamic typing with dynamic checking and avoid common but ambiguous terms such as strong typing.

因为它不是语言固有属性,而是编译器的行为,搞清这点就不会产生误解了。可能有人会问,既然Statically Typed 不是语言固有属性,那C\C++、Java的类型声明又怎么解释呢?前面说了,那叫「Explicitly Typed」,类型是语言语法的一部分,但到底是静态检查还是运行期检查,或者是根本不检查,那就是编译器解释器的行为了。比如PHP有Type Hint,看上去就像 Explicitly Typed,但它是运行到那行代码才检查,仍然不是Statically Checked。
好了,现在静态类型动态类型算是搞清楚了吧。


那 Type Safety 呢?

Type safety is the property that no primitive operation ever applies to values of the wrong type. By primitive operation we mean not only addition and so forth, but also procedure application. A safe language honors the abstraction boundaries it erects.

这也算是通俗的解释了,符合大众印象,大家所理解的强类型、类型安全等,通常都是指运算符和函数调用,比如将原本作用于Int的“*”去用到字符串上是不合法的,程序不会继续往下执行。

为什么C/C++ 是Type unsafe呢?注意,type是和value绑定到一起的,所以:

int a = 4;
char* s = (char*)a; //假设类型转换OK通过编译
void f(char* s);
f(s); // unsafe

C/C++ 本不具备一个 Sound Type System,即它的类型系统本身就并不能保证安全。

为什么大家认为Python是强类型呢?也就是说他们倾向于认为Python是类型安全的?CPython解释器就是Python语言事实上的标准,所以我们就直接看Python解释器的行为了,它会在运行期检测类型错误,程序会中断执行:

class A:
  def halo(self):
    print "A"

class B: 
  pass

A.halo(B()) # 抛出 TypeError,如果B继承自A则不会报错

当然,ctypes这种东西我们就不考虑了。

相比之下,JavaScript就很明显谈不上类型安全,但这也取决于你的定义,如果你将类型安全的定义放宽,也可以认为 JavaScript 类型安全,比如调用不存在的方法 JS 也会中断执行。

顶一下
(0)
0%
踩一下
(0)
0%
相关评论
我要评论
用户名: 验证码:点击我更换图片