静态类型和动态类型,所谓强类型语言,指的是错误地使用了类型时,编译器将引发错误;所谓动态类型(也叫松散类型或弱类型)语言,指的是为了执行程序,运行时会将一种类型转换为另一种类型,或者编译器没有实现类型系统。哪种语言更好呢?这存在很大的争议,计算机科学家看重强类型语言的正确性和安全性,而其他人则看重动态语言的简单性和开发速度。
下面是静态类型语言的一些优点。
- 性能高于动态类型语言。
- Bug通常会被编译器发现。
- 代码编辑器可提供代码补全和其他功能。
- 数据完整性更好。
下面是动态类型语言的一些优点。
- 使用动态类型语言编写软件的速度通常更快。
- 无须为执行代码而等待编译器完成编译。
- 动态类型语言通常不那么死板,因此有些人认为变更代码更容易。
- 有些人认为动态类型语言学习门槛更低。
在Go中,程序员可显式地声明类型,也可让编译器推断类型。在本文中,我们将显式地声明类型,以帮助您理解。如下是一个向终端打印消息的程序。
package main
import (
"fmt"
)
func sayHello(s string) string {
return "Hello " + s
}
func main() {
fmt.Println(sayHello("George"))
}
如果您不能完全理解程序清单,也不用担心。这里的重点是函数sayHello的声明。从参数声明可知,这个函数接受一个类型为string的参数;这个函数的返回值也是字符串。因此,编译这个程序时,编译器将检查传递给这个函数的参数是否是字符串;如果不是,编译器将引发错误。这正是我们希望的,因为这意味着错误可能根本不会让用户遇到。
为了比较强类型语言和动态类型语言,下面来看一个JavaScript示例。JavaScript是一种使用广泛的动态类型语言,如果您不熟悉,也没关系。这里的重点是看看它在处理类型方面有何不同。
如下是一个简单的JavaScript函数,它接受两个值,将它们相加并返回结果。
var addition = function (a, b) {
return x + y;
};
给这个函数提供两个数字时,它能够正确地运行。
addition(1,3)
4
然而,如果向它传递一个数字和一个字符串,结果将很怪异。
addition(1,"three")
1three
在这种情况下,这个函数返回一个字符串。怎么会这样呢?虽然JavaScript有类型的概念,但其类型使用规则非常宽松。在这个示例中,JavaScript对数字值执行类型转换,将其转换为字符串,因此返回字符串1three。JavaScript提供的这种灵活性虽然很有吸引力,但可能导致微妙乃至灾难性的Bug。
假设有个程序使用上述addition函数来接受输入并将其存储到数据库中。数据库通常有数据类型的概念,很多还有整数的概念。整数是没有小数部分的数字,可正可负。如果数据库将字段定义成了整型,就会要求提供给该字段的值为整数。
前述JavaScript函数addition可能返回一个字符串,也可能返回一个整数。如果传递给它的值至少有一个字符串,返回的就是字符串。如果这个返回值被插入到需要整数的数据库字段中,将引发错误。更糟糕的是,这种错误发生在运行阶段,这意味着它将影响使用程序的用户。这种错误除非得到妥善处理,否则可能导致程序崩溃。
而在使用Go语言编写的函数中,对参数和返回值的类型都做了声明。
如下是一个使用Go语言编写的函数,这个函数指出它接受两个int值,并返回一个int值。即便不看这个函数的实现,也知道它接受两个整数并返回一个整数。如果程序员错误地将一个字符串传递给这个函数,编译器将捕获这种错误。
package main
import (
"fmt"
)
func addition(x int, y int) int {
return x + y
}
func main() {
fmt.Println(2,4)
}
如下所示的示例中,向函数传递了类型不正确的参数。在这个示例中,将在编译阶段发现这种错误,避免用户遭遇软件崩溃。
package main
import (
"fmt"
)
func addition(x int, y int) int {
return x + y
}
func main() {
var s string = "three"
fmt.Println(addition(1, s))
}
如果您尝试运行这个程序,将出现编译错误。编译错误提供了有用的信息,让您知道出现错误的原因。在这里,原因是在需要int的地方使用了字符串。
Go编译器还能捕获其他常见的错误,如传递的参数太多或太少。
酷客教程相关文章:
评论前必须登录!
注册