在道格拉斯·克罗克福德(Douglas Crockford)的《JavaScript:The Good Parts》中,他在继承章节中提到:
经典继承的另一个好处是它包括类型系统的规范。这主要使程序员不必编写显式的转换操作,这是一件非常好的事情,因为在转换时,类型系统的安全性丧失了。
那么首先,安全到底是什么?防止数据损坏,黑客或系统故障等?
类型系统的安全益处是什么?是什么让类型系统与众不同,才能提供这些安全优势?
在道格拉斯·克罗克福德(Douglas Crockford)的《JavaScript:The Good Parts》中,他在继承章节中提到:
经典继承的另一个好处是它包括类型系统的规范。这主要使程序员不必编写显式的转换操作,这是一件非常好的事情,因为在转换时,类型系统的安全性丧失了。
那么首先,安全到底是什么?防止数据损坏,黑客或系统故障等?
类型系统的安全益处是什么?是什么让类型系统与众不同,才能提供这些安全优势?
Answers:
类型系统消除了非法程序。考虑以下Python代码。
a = 'foo'
b = True
c = a / b
在Python中,该程序失败;它会引发异常。在Java,C#,Haskell之类的语言中,这甚至都不是合法程序。您完全避免了这些错误,因为在输入程序集中根本不可能发生这些错误。
同样,更好的类型系统可以排除更多错误。如果我们跳到超高级类型系统,我们可以这样说:
Definition divide x (y : {x : integer | x /= 0}) = x / y
现在,类型系统保证没有任何0分频错误。
这是系统可以防止的错误类型的简要列表
请记住,这也是在编译时。无需编写100%代码覆盖率的测试来简单地检查类型错误,编译器将为您完成:)
好吧,让我们研究一下所有类型最简单的系统,即简单地输入lambda演算。
基本上有两种类型
Type = Unit | Type -> Type
并且所有术语都是变量,lambda或应用程序。基于此,我们可以证明任何类型良好的程序都将终止。永远不会出现程序被卡住或永远循环的情况。在正常的lambda演算中这是无法证明的,因为那是不正确的。
想想看,我们可以使用类型系统来保证我们的程序不会永远循环,而是很酷吧?
动态类型系统可以提供与静态类型系统相同的保证,但是可以在运行时而不是在编译时提供。实际上,由于它是运行时,因此您实际上可以提供更多信息。但是,您失去了某些保证,尤其是关于静态属性(例如终止)的保证。
因此,动态类型并不排除某些程序,而是将格式错误的程序路由到定义明确的操作,例如引发异常。
因此,总的来说,长短是类型系统排除某些程序。许多程序以某种方式被破坏,因此,对于类型系统,我们避免了这些破坏的程序。
类型系统可以帮助您避免简单的编码错误,或者允许编译器为您捕获这些错误。
例如,在JavaScript和Python中,以下问题通常仅在运行时才发现-并且取决于测试条件的质量/稀有性,实际上可能使其进入生产环境:
if (someRareCondition)
a = 1
else
a = {1, 2, 3}
// 10 lines below
k = a.length
强类型语言会强制您明确声明它a
是一个数组,并且不允许您分配整数。通过这种方式,没有任何机会a
不会有length
-甚至在少数情况下。
在软件开发周期中,您越早发现错误,则修复成本就越低。考虑一个导致最大客户或所有客户丢失数据的错误。如果仅在真正的客户丢失数据之后才发现这种错误,那么您的公司就可能灭亡!显然,在将其转移到生产环境之前,查找和修复该错误的成本更低。
即使对于代价较低的错误而言,如果涉及测试人员,则花费的时间和精力也要比程序员能够找到并修复它的时间和精力更多。如果不将其检入到源代码管理中,其他程序员可以在该代码中构建依赖它的软件,那么它会更便宜。类型安全性可防止某些类型的错误甚至无法编译,从而消除了这些错误的几乎所有潜在成本。
但这还不是全部。就像任何使用动态语言编程的人都会告诉您的那样,有时候您的程序只是编译就很好了,因此您可以尝试其中的一部分而不必花费所有细节。在安全性和便利性之间需要权衡取舍。单元测试可以减轻使用动态语言的某些风险,但是编写和维护良好的单元测试有其自身的成本,其成本可能比使用类型安全的语言要高。
如果您正在试验,如果您的代码仅使用一次(例如一次性报告),或者您处于无论如何都不想编写单元测试的情况下,那么动态语言可能是完美的选择为了你。如果您有一个大型应用程序,并且希望在不破坏其余部分的情况下进行更改,那么输入安全性可以节省生命。安全捕获的错误类型恰恰是重构时人类容易忽略或犯错的错误类型。
介绍
类型安全可以使用静态类型(编译的静态类型检查)和/或运行时(评估的动态类型检查)语言来实现。根据Wikipedia的描述,“ ... 强类型系统”被认为是其中不可能发生未经检查的运行时类型错误的系统(ed Luca Cardelli)。换句话说,不存在未经检查的运行时错误称为安全性或类型安全性...'
安全-静态类型检查
通常,在C,C ++和Haskell等语言中,类型安全已与静态类型同义,这些语言旨在在编译时检测类型不匹配。这样做的好处是在执行程序时避免了潜在的未定义或容易出错的情况。在存在指针类型可能不匹配的风险的情况下,例如,如果未检测到可能导致灾难性后果的情况,这将是无价的。在这种意义上,静态类型被认为是内存安全的同义词。
静态类型化并不完全安全,但是可以提高安全性。即使是静态类型的系统也可能造成灾难性的后果。许多专家认为,静态类型可用于编写更健壮和更不易出错(关键任务)的系统。
静态类型的语言可以帮助减少数据丢失或数值工作精度损失的风险,这种风险可能是由于不匹配或截断双精度浮点数或整数和浮点数类型不匹配而引起的。
使用静态类型的语言具有效率和执行速度的优势。运行时受益于不必在执行期间确定类型。
安全-运行时类型检查
例如,Erlang是一种在虚拟机上运行的类型声明式,动态类型检查的语言。Erlang代码可以按字节编译。Erlang被认为是可用的最重要的关键任务,容错语言,据报道,Erlang具有九个9的可靠性(每年99.9999999%或不超过31.5毫秒)。
某些语言(例如Common Lisp)不是静态类型的,但是可以根据需要声明类型,这有助于提高速度和效率。还应注意,在评估循环下,许多更广泛使用的解释语言(例如Python)是以静态类型的语言(例如C或C ++)编写的。上面的定义认为Commom Lisp和Python都是类型安全的。
1 + "1"
引发异常,而在PHP(弱类型)中1 + "1"
产生2
(字符串"1"
自动转换为integer 1
)。
类型系统的安全利益就丧失了。
那么首先,安全到底是什么?防止数据损坏,黑客或系统故障等?
类型系统的安全益处是什么?是什么让类型系统与众不同,才能提供这些安全优势?
我觉得类型系统有这样的负面看法。类型系统更多地是要保证而不是证明没有错误。后者是类型系统的结果。一种用于编程语言的类型系统是一种在编译时生成程序符合某种规范的证明的方式。
一个人可以编码为一种类型的规范的种类取决于语言,或更直接地取决于语言的类型系统的强度。
最基本的规范是关于功能的输入/输出行为以及功能主体内部有效性的保证。考虑一个函数头
f : (Int,Int) -> String
一个好的类型系统将确保f仅应用于在求值时会产生一对Int的对象,并保证f会始终产生一个字符串。
某些语言的语句(例如if-then块)没有输入/输出行为。这里的类型系统保证了块中的每个声明或语句都是有效的;将操作应用于正确种类的对象。这些保证是可组合的。
同样,这确实提供了某种内存安全条件。您正在处理的报价是关于铸造的。在某些情况下,强制转换很好,就像将32位Int转换为64位Int一样。但是,通常,它会使类型系统崩溃。
考虑
Foo x = new Foo(3,4,5,6);
f((Int)x,(Int)x);
由于强制转换,x变成了Int,因此从技术上讲,上面的代码确实进行类型检查;但是,它确实无法实现类型检查的目的。
可以构成另一种更好的类型系统的一件事是,禁止将(A)x强制转换为X,其中x在案例为B之前,除非B是A的子类型(或子对象)。子类型理论的思想已在安全性中使用。消除整数上溢/下溢攻击的可能性。
摘要
类型系统是一种证明程序符合某种规格的方法。类型系统可以提供的好处取决于所使用类型系统的强度。
类型系统尚未提及的一个优点集中于这样一个事实,即读取许多程序而不是编写更多的程序,并且在许多情况下,类型系统可以允许以简明且容易的方式指定许多信息。被阅读代码的人消化。尽管参数类型不能代替描述性注释,但大多数人会发现它读起来更快:“ int Distance;”。要么Distance As Int32
而不是阅读“距离必须是+/- 2147483647的整数”;此外,参数类型可以帮助缩小API的特定实现恰好与调用者有权依赖的范围之间的差距。例如,如果API的特定Javascript实现使用它在这将迫使任何字符串到数字形式的方法参数,可能不清楚呼叫者是否允许依靠这样的行为,或者API的其他实现方式可能会发生故障,如果给定的字符串。拥有其参数被指定为法Double
会明确指出任何字符串值在传递之前必须由调用者强制执行;具有一个方法,该方法的重载可以接受,Double
而另一个可以接受String
这样会更清楚地表明,允许持有字符串的呼叫者按原样传递它们。
那么首先,安全到底是什么?防止数据损坏,黑客入侵或系统故障等?
所有其他答案等等。通常,“类型安全”仅表示编译器成功编译的所有程序都不会包含类型错误。
现在,什么是类型错误?原则上,您可以将任何不希望的属性指定为类型错误,并且某些类型系统将能够静态地确保没有程序出现此类错误。
上面的“属性”是指某种适用于您的程序的逻辑命题,例如,“所有索引都在数组范围内”。其他类型的属性包括“所有引用的指针均有效”,“此程序不执行任何I / O”或“此程序仅对/ dev / null执行I / O”等。可以指定类型并以这种方式检查类型,具体取决于类型系统的表现力。
依赖类型系统是最通用的类型系统之一,通过它可以强制执行几乎任何您喜欢的属性。这不一定容易这样做,虽然,因为复杂性都受到不完整的礼貌哥德尔。