动态静态类型、强弱类型、类型安全

动态语言和静态语言

动态语言变量类型在运行时确定,可以不指定变量类型。静态语言变量类型在编译时确定,需要在变量申明时,明确指定变量类型

example

#php
$a = 10;  //此时类型不明,需要程序运行后确定

#golang
a int = 10 //明确变量类型为int

强类型与弱类型语言

从维基百科获得陈述如下: 这两个术语并没有非常明确的定义,但主要用以描述编程语言对于混入不同数据类型的值进行运算时的处理方式。强类型的语言遇到函数引数类型和实际调用类型不符合的情况经常会直接出错或者编译失败;而弱类型的语言常常会实行隐式转换,或者产生难以意料的结果。

来自stackoverflow关于Is C strongly typed?这个问题多数人赞同的答案这样描述: “Strongly typed” and “weakly typed” are terms that have no widely agreed-upon technical meaning. Terms that do have a well-defined meaning are Dynamically typed and Statically typed

关于强弱类型这个混淆的 “定义” 存在不同程度的差异,没有权威的定义,我们可以按照自己的理解来分类各个语言。

  • 禁止类型转换。某个类型的值,不论是不是以显式或隐式的方式,都不可转换为另一个类型。这是一个过于严苛的定义[来源与维基百科],好像绝大多数语言都不满足于这个定义。

example

# C 进行算术运算 会隐式类型转换 
int a = 3;
float b = 1.5;
int m = a / b;
printf("%d\n",m); // output: 2

# C 可以进行强制类型转换
float f = 3.0;
int fti = (int)f;
printf("%d\n",fti); //output: 3

# Golang 不支持隐式类型转换 类型不一致 导致编译错误
var a int = 3
var b float64 = 1.5
var m int = a / b
fmt.Println(m) //invalid operation: a / b (mismatched types int and float64)

# Golang 可以进行类型兼容的强制类型转换
var a float64 = 3.0
var b int = int(a)
fmt.Println(b)

# 按照这个说法,C可以进行隐式类型转换和显式的强制类型转换,将要被归类于弱类型语言
# Golang 由于可以进行显式的强制类型转换,也要被定义为弱类型语言 但是Golang官方定义其为强类型语言 所以这种对强弱类型的定义说明有问题
  • 把“强类型语言”称呼保留给省略隐式类型转换(就是说编译器为了利益编程者而插入的转换)的语言。这意味着对于这个定义支持者,如果类型必须通过“强制”的显式符号来转换,那么该编程语言是强类型的。这个定义是对上面的定义的条件放宽,似乎被更多的人接受

example

# C 进行算术运算 会隐式类型转换 
int a = 3;
float b = 1.5;
int m = a / b;
printf("%d\n",m); // output: 2

# Golang 不支持隐式类型转换 类型不一致 导致编译错误
var a int = 3
var b float64 = 1.5
var m int = a / b
fmt.Println(m) //invalid operation: a / b (mismatched types int and float64)

# C 可以进行隐式类型转换 将要被归类于弱类型语言
# Golang 由于无法进行隐式类型转换 要被定义为强类型语言

类型安全

类型安全表明编程语言阻止或防止类型错误的程度,其根据在于该门编程语言是否提供保障类型安全的机制。类型错误是由程序的常量、变量、方法、函数的不同数据类型之间的差异引起的错误或不良的程序行为,如将整形int视为浮点类型float。有的时候也用“类型安全”形容某个程序,判别的标准在于该程序是否隐含类型错误。类型安全的编程语言与类型安全的程序之间,没有必然联系。好的程序员可以使用类型不那么安全的语言写出类型相当安全的程序,相反的,差一点儿的程序员可能使用类型相当安全的语言写出类型不太安全的程序。绝对类型安全的编程语言暂时还没有

参考

维基百科-类型安全
什么是类型安全
维基百科-强弱类型