【问题标题】:Does a type safe language needs to be statically typed?类型安全语言是否需要静态类型化?
【发布时间】:2015-01-20 10:31:26
【问题描述】:

我试图理解语言类型安全意味着什么。在动态类型语言中,类型检查是在运行时执行的,例如,如果我运行以下 PHP 代码:

<?php
class MyClass
{ 
}

// Create a MyClass instance
$mc = new MyClass();

// Create an int variable
$i = 1234;

// Add $mc and $i
$result = $mc + $i;
?>

我会收到一个错误,因为+ operator 不支持MyClass 数据类型。所以基本上类型检查是在运行时执行的。

类型安全是否意味着无论是在编译时还是运行时都执行类型检查,还是意味着类型检查必须仅在编译时执行,因此必须明确地为每个变量指定数据类型(如 C、Pascal、Java 等)。

【问题讨论】:

  • 对于这种特殊情况,有某种类型安全,但如果你说function x() { $i = 0; if (true) { $i = "bla"; } return $i; }...
  • 顺便说一句。您的示例将导致 1235,因此那里也没有安全性
  • @Royal Bg 如果一种语言在运行时执行类型检查并在发现类型错误时停止程序,那么这种语言是否称为类型安全语言?
  • 很可能不是。在某些论文中,您可能会发现这些语言是有限类型安全语言或在有限上下文中类型安全。对我来说,没有类型安全,如果您可以将其隐藏在 if() 块中
  • C 不是完全类型安全的。如果是这样,它就不会像它那样有那么多未定义的行为。 C# 不一定是静态的、强类型的,但它被认为是类型安全的。但是话又说回来,如果您不希望它是,它不必是。 Java 被设计为类型安全的,但仍有一系列异常需要您抛出/处理,以防类型系统让您失望(BigDecimal.divideNullPointerException、...)

标签: php programming-languages type-safety dynamic-typing static-typing


【解决方案1】:

“类型安全”通常表示“内存类型安全”,即不能将包含一种类型的内存视为另一种类型。

根据这个定义,大多数高级语言,包括动态类型语言,都是类型安全的,因为任何错误使用类型的尝试都会导致错误(编译时或运行时)。

因此,类型安全主要是低级语言的一个问题,尤其是 C 和 C++。这些问题通常涉及指针或强制转换(例如 C++ 中的reinterpret_cast)。

C# 是介于这两组之间的一个有趣案例:默认情况下它是类型安全的,但您可以使用 unsafe 关键字关闭部分代码的类型安全(通常出于性能或互操作原因)。


但是,如果您将类型安全与静态类型结合起来,并不一定意味着必须编写类型。许多静态类型安全语言,尤其是函数式语言,或受其启发的语言,都使用type inference。这意味着编译器可以根据分配给它的内容自行确定变量的类型,因此您不必键入它。这方面的示例是 C++ 中的 auto 关键字和 C# 中的 var

【讨论】:

  • 类型安全不是问题,因为它可以防止你犯错并帮助你确保你知道自己在做什么(PHP 就像用你不知道的食材做饭) .而且在我个人看来,类型安全语言中的类型推断并不好,因为它让你很容易失去关于变量类型的概述。咦,你没有?然后是几十年后必须扩展或更改您的代码块的人。
【解决方案2】:

答案是否定的。 Python 是动态但强类型语言的一个例子:

>>> "foo" + 42
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: cannot concatenate 'str' and 'int' objects

Haxe 是编译时类型安全语言的一个示例,它仍然不需要静态声明类型:

class Test {
    static function main() {
        trace(10 * Test.some());
    }

    static function some() {
        return "foo";
    }
}

> Build failure
> Test.hx:3: characters 19-30 : String should be Int

这是通过type inference 完成的。

【讨论】:

  • 如果没有静态声明,Haxe 如何知道编译类型变量的数据类型,我可以更改 if 块内的数据类型,防止 Haxe 知道数据类型将在编译时。
  • @Steve:在某些时候,您必须为 var 分配一些东西,这就是 Haxe 推断其类型的地方。您还可以将变量声明为动态变量,就像在 Python 中一样。见old.haxe.org/ref/type_infer
  • 我的意思是如果 Haxe 在编译时执行类型检查,并且它还支持创建变量而不显式指定其数据类型,这意味着我可以创建一个 if 块来更改变量的数据类型在运行时,然后在不支持这种新更改的数据类型的语句中使用此变量。例如:var i = 123; if (something) i = new MyClass(); var 结果 = i + 其他变量;
  • 所以这就像变量是静态声明的,但没有实际指定数据类型!
  • 在那种情况下,我不认为这是一个正确的陈述:“编译时类型安全的语言,它仍然不需要静态声明类型”,我不认为编译时类型安全的语言可以允许在运行时更改数据类型。
猜你喜欢
  • 2012-12-12
  • 2011-12-03
  • 2012-10-31
  • 2020-08-02
  • 1970-01-01
  • 1970-01-01
  • 2016-09-26
相关资源
最近更新 更多