“类型安全”是什么意思?
当前回答
类型安全的代码只访问它被授权访问的内存位置,并且只能以定义良好的、允许的方式访问。 类型安全代码不能在对象上执行对该对象无效的操作。c#和VB。NET语言编译器总是生成类型安全的代码,这些代码在JIT编译期间被验证为类型安全的。
其他回答
试试这个解释……
TypeSafe意味着在编译时静态检查变量是否有适当的赋值。例如,考虑一个字符串或整数。这两种不同的数据类型不能交叉赋值(也就是说,不能将整数赋值给字符串,也不能将字符串赋值给整数)。
对于非类型安全的行为,考虑如下:
object x = 89;
int y;
如果你试图这样做:
y = x;
编译器抛出一个错误,表示它不能转换一个系统。对象转换为整数。你需要明确地这样做。一种方法是:
y = Convert.ToInt32( x );
上面的赋值不是类型安全的。类型安全赋值是指类型可以直接相互赋值。
非类型安全的集合在ASP。NET(例如,应用程序、会话和视图状态集合)。关于这些集合的好消息是(尽量减少多个服务器状态管理方面的考虑),您可以在这三个集合中的任何一个中放入几乎任何数据类型。坏消息是:因为这些集合不是类型安全的,所以在取回值时需要适当地强制转换。
例如:
Session[ "x" ] = 34;
工作很好。但是要将整数值赋回,你需要:
int i = Convert.ToInt32( Session[ "x" ] );
阅读泛型,了解该工具帮助您轻松实现类型安全集合的方式。
c#是一种类型安全语言,但请关注有关c# 4.0的文章;有趣的动态可能性正在逼近(c#实际上得到了严格的选项:关闭,这是一件好事吗?我们将会看到)。
来自文科专业而不是计算机科学专业的解释:
当人们说一种语言或语言特性是类型安全的时,他们的意思是该语言将有助于防止,例如,将非整数的东西传递给某个期望整数的逻辑。
例如,在c#中,我将一个函数定义为:
void foo(int arg)
编译器会阻止我这样做:
// call foo
foo("hello world")
在其他语言中,编译器不会阻止我(或者没有编译器…),所以字符串将被传递给逻辑,然后可能会发生一些不好的事情。
类型安全语言试图在“编译时”捕获更多。
缺点是,使用类型安全语言,当你有一个像“123”这样的字符串,你想像整型一样对它进行操作时,你必须写更多的代码来将字符串转换为整型,或者当你有一个像123这样的整型,并且想在一个像“答案是123”这样的消息中使用它时,你必须写更多的代码来将它转换/强制转换为字符串。
为了更好地理解,请观看下面的视频,该视频演示了类型安全语言(c#)和非类型安全语言(javascript)的代码。
http://www.youtube.com/watch?v=Rlw_njQhkxw
现在来看长文本。
类型安全意味着防止类型错误。当一种类型的数据类型在不知不觉中被分配给另一种类型时,就会发生类型错误,我们会得到不想要的结果。
例如,JavaScript不是一种类型安全语言。在下面的代码中,“num”是一个数值变量,“str”是字符串。Javascript允许我做“num + str”,现在猜测将它做算术或串联。
现在对于下面的代码,结果是“55”,但重要的一点是,它将执行什么样的操作造成了混乱。
这是因为javascript不是一种类型安全的语言。它允许不受限制地将一种类型的数据设置为另一种类型。
<script>
var num = 5; // numeric
var str = "5"; // string
var z = num + str; // arthimetic or concat ????
alert(z); // displays “55”
</script>
c#是一种类型安全语言。它不允许将一种数据类型分配给另一种数据类型。下面的代码不允许在不同的数据类型上使用“+”运算符。
类型安全不仅是编译时约束,也是运行时约束。我觉得即使过了这么久,我们也可以进一步明确这一点。
与类型安全相关的主要问题有两个。内存**和数据类型(与其对应的操作)。
内存* *
一个字符通常需要每个字符1个字节,或者8位(取决于语言,Java和c#存储unicode字符需要16位)。 int需要4个字节,或32位(通常)。
视觉:
字符 : |-|-|-|-|-|-|-|-|
int : |-|-|-|-|-|-|-|-| |-|-|-|-|-|-|-|-| |-|-|-|-|-|-|-|-| |-|-|-|-|-|-|-|-|
类型安全语言不允许在运行时将int类型插入到char类型中(这会抛出某种类型的类强制转换或内存溢出异常)。但是,在一种类型不安全的语言中,您将覆盖现有数据的相邻内存多3个字节。
Int >> char:
|-|-|-|-|-|-|-|-| |?|?|?|?|?|?|?|?| |?|?|?|?|?|?|?|?| |?|?|?|?|?|?|?|?|
在上面的例子中,右边的3个字节被覆盖,所以任何指向该内存的指针(比如3个连续的字符),希望得到一个可预测的char值现在都是垃圾。这将导致您的程序中出现未定义的行为(或者更糟,可能会在其他程序中出现,这取决于操作系统如何分配内存——目前不太可能)。
**虽然第一个问题在技术上不是关于数据类型的,但类型安全语言固有地解决了这个问题,并且它向那些不知道内存分配“看起来”如何的人直观地描述了这个问题。
数据类型
更微妙和直接的类型问题是两种数据类型使用相同的内存分配。取int型和unsigned int型。两者都是32位。(也可以是char[4]和int,但更常见的问题是uint vs. int)。
|-|-|-|-|-|-|-|-| |-|-|-|-|-|-|-|-| |-|-|-|-|-|-|-|-| |-|-|-|-|-|-|-|-|
|-|-|-|-|-|-|-|-| |-|-|-|-|-|-|-|-| |-|-|-|-|-|-|-|-| |-|-|-|-|-|-|-|-|
类型不安全语言允许程序员引用正确分配的32位span,但当将无符号整型的值读入整型的空间时(反之亦然),我们再次遇到未定义的行为。想象一下这可能会给银行项目带来的问题:
“伙计!我透支了30美元,现在我还剩65,506美元!!”
...当然,银行程序使用更大的数据类型。,)哈哈!
正如其他人已经指出的,下一个问题是对类型的计算操作。这一点已经得到了充分的讨论。
速度vs安全
今天的大多数程序员都不需要担心这些事情,除非他们使用的是C或c++之类的东西。这两种语言都允许程序员在运行时轻易地违反类型安全(直接内存引用),尽管编译器尽最大努力将风险降至最低。然而,这也不全是坏事。
这些语言计算速度如此之快的一个原因是它们不需要像Java那样在运行时操作期间验证类型兼容性。他们认为开发人员是一个很理性的人,不会把字符串和int放在一起,因此,开发人员获得了速度/效率的奖励。
类型安全不应与静态/动态类型或强/弱类型相混淆。
类型安全语言是这样一种语言,在这种语言中,只能对数据执行数据类型所允许的操作。也就是说,如果您的数据是X类型,而X不支持操作y,那么该语言将不允许您执行y(X)。
这个定义没有设置何时检查的规则。它可以在编译时(静态类型)或在运行时(动态类型),通常通过异常进行。它可以两者兼有:一些静态类型语言允许您将数据从一种类型转换为另一种类型,并且必须在运行时检查转换的有效性(假设您试图将对象转换为消费者—编译器无法知道它是否可接受)。
Type-safety does not necessarily mean strongly typed, either - some languages are notoriously weakly typed, but still arguably type safe. Take Javascript, for example: its type system is as weak as they come, but still strictly defined. It allows automatic casting of data (say, strings to ints), but within well defined rules. There is to my knowledge no case where a Javascript program will behave in an undefined fashion, and if you're clever enough (I'm not), you should be able to predict what will happen when reading Javascript code.
类型不安全编程语言的一个例子是C语言:在数组边界之外读取/写入数组值的规范没有定义行为。预测将会发生什么是不可能的。C是一种具有类型系统的语言,但不是类型安全的。