【问题标题】:Which programming languages don't have runtime exceptions?哪些编程语言没有运行时异常?
【发布时间】:2016-02-11 15:36:27
【问题描述】:

字符串名称=空; 名称.ToLower();

在大多数语言中,此类代码都可以编译。哪些语言会在编译时捕获此类错误?

目前我知道的只有 elm:http://elm-lang.org

【问题讨论】:

  • 您对一开始就不允许使用string name = null 的语言感兴趣吗?
  • @zenith 我对可以在编译时捕获尽可能多的错误的语言很感兴趣。所以是的,我也对对象不能为空的语言感兴趣。
  • 似乎更好的问题标题可能是“哪些语言在编译时捕获尽可能多的错误?”在这种情况下。
  • @zenith 我想它是一样的。你不能更进一步地捕捉到尽可能多的错误,而不是没有运行时异常。编译器将无法检查您的业务逻辑是否正确。

标签: exception strong-typing


【解决方案1】:

Rust 在编译时防止了很多错误。 Rust 没有运行时异常(除了使程序崩溃的panic!),而是使用返回值进行错误处理。

let name = None; // error: mismatched types
let name: Option<String> = None; // ok

name.to_lowercase(); // error: no method named `to_lowercase` found for type `Option`

// correct:
match name {
    None => { /* handle None */ },
    Some(value) => { value.to_lowercase(); },
}

// or to ignore None and crash if name == None
name.unwrap().to_lowercase();

Rust 的核心概念之一是其他语言没有的 (afaik) 是 lifetimes,它可以防止在编译时出现悬空引用。然而,这是垃圾收集和引用计数语言不需要的东西。


Go 没有例外。像 Rust 一样,它使用返回值来表示错误。但它不是空安全的:

// strings can't be nil:
var name string = nil // error: cannot use nil as type string in assignment

// string pointers can:
var name *string = nil // ok

string.ToLower(*name) // panic: runtime error: invalid memory address

以下语言确实具有异常处理功能,但仍可能有助于回答问题。


Swift 也比平均安全,但它确实包含运行时异常。但是,Swift 的异常比 C++、Java、C# 等的异常更明确(例如,您必须在每次调用抛出函数前加上 try,并且函数声明必须指定该函数是否可以抛出)。

let name = nil // error: type of expression is ambiguous without more context
let name: String? = nil // ok

name.lowercaseString // error: value of optional type 'String?' not unwrapped; did you mean to use '!' or '?'?
name!.lowercaseString // will crash at runtime with: fatal error: unexpectedly found nil while unwrapping an Optional value
name?.lowercaseString // calls method only if name != nil

Kotlin 是一种更安全的 JVM 语言,它也可以编译为 JavaScript。 Kotlin 也有例外。

val name = null
name.toLowerCase() // compile-error

if (name != null)
    name.toLowerCase() // ok

name?.toLowerCase() // call only if non-null

Ada 是一种为安全关键目的而设计的语言。根据http://www.adaic.org/advantages/features-benefits/,它的“许多内置检查允许编译器或链接器检测在基于 C 的语言中只能在运行时捕获的错误”。

【讨论】:

  • 这个答案太棒了。
  • 需要注意的一点是,如果您使用unwrap(),您可以在 rust 中出现运行时异常。类似于 swift 的 ! 运算符,但更容易搜索和避免。
  • unwrap() 在 Rust 中会引起恐慌,即程序终止,这与异常不同。它还有 ? 运算符,具有类似的效果。
  • 我正想问为什么不是 Elm,但当我回答这个问题时,我意识到 Elm 甚至不在身边。
  • @HedgepigMatt Elm 就在身边。我在问题中提到过。
【解决方案2】:

Here 是默认情况下不允许变量为空的语言列表。

这使它们更加安全,在编译时阻止所有NullPointerExceptions,并且更清晰,因为您只需查看代码就知道在哪里可以传递 null 和不可以传递。

这些语言中的大多数还提供许多其他编译时安全功能。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-02
    • 2011-02-21
    • 1970-01-01
    • 1970-01-01
    • 2012-10-06
    • 1970-01-01
    • 1970-01-01
    • 2011-01-06
    相关资源
    最近更新 更多