【问题标题】:Is there a way to make the Swift compiler ignore errors?有没有办法让 Swift 编译器忽略错误?
【发布时间】:2018-03-18 15:37:37
【问题描述】:

我想在编译我的 Swift 代码时忽略错误。例如,您正在编写一个尚未在您的应用程序中使用的类并且其中有错误,或者如果编译器只是对所有这些安全措施感到愚蠢,那么您仍然可以编译它吗?你可以ma​​ke编译器编译它吗,即使它有点hack-ish?

或者换句话说,我怎样才能让错误被视为警告?

【问题讨论】:

  • 编译过程中的错误是程序无法恢复的问题——与警告不同,错误表明编译器无法继续编译,因为生成的程序没有意义.你能举一个你正在尝试做的事情的具体例子吗?
  • 例如,为什么不能有一个在super.init 调用时未初始化的let 常量?这很愚蠢。 根据超类的定义,它不在超类中使用。无论如何,我不在乎是否有意义。我确实询问编译器是否有意义。我希望它编译,而不是质疑它的意义。
  • @Nullcaller 这个错误实际上是有道理的。 super.init,一旦完成了其所有属性的初始化,就完全可以在其自身上调用方法。您可能以依赖于 let var; 的方式覆盖了该方法;如果您在初始化该 var 之前调用 super.init,您将遇到麻烦。这与在调用函数/方法之前必须完全初始化 self 完全一致——你不知道它会做什么,这可能取决于你是否完全初始化。
  • 您熟悉未定义行为的概念吗?在要求编译器不检查“有意义”时,您要求的是具有未定义行为的可执行文件。也就是说,Swift 确实提供了一种“定义明确的未定义行为”,可以让你绕过一些初始化规则:隐式展开的可选属性。但是,您不应该习惯在生产代码中使用它们。它们是针对特定情况的解决方法,而不是通过编译器强制执行不完整代码的方法。
  • 像 Python 或 Ruby 这样的解释型语言可以为您提供所需的灵活性和静态分析。

标签: swift compiler-errors compilation


【解决方案1】:

不,没有办法做到这一点。编译器错误是错误而不是警告,其原因是:它们是源代码中不可恢复的问题。

程序可能存在的几类错误可能会或可能不会在编译器的不同级别捕获:

  1. 语法错误:这些是您的源代码中的错误,使其成为无效程序。不可能要求编译器在语法错误之后继续编译程序,因为代码本身是无效的。例如,您不能期望编译器将 ?123?5445?,asdf,34124:::::!22 编译成 Swift 程序,因为它不是 Swift 代码。
  2. 语义错误:这些错误是您编写的代码是有效的 Swift,但在语义上可能没有意义。例如,func foo(_: String) {}; foo(5) 有一个语义错误:您将 Int 传递给期望 String 的函数。过去的语义验证,编译器需要决定为给定的表达式生成什么中间语言代码;它为foo(5) 生成什么代码?可以破坏寄存器和堆栈状态以将任何值传递到任何地方,但这确实违反了 Swift 所代表的一切。
    • 这里也有潜在的子类别。以上是类型不匹配错误;您上面提到的super.init 错误是语言规则的强制执行(在将self 传递给函数或在self 上调用方法之前,必须初始化所有实例变量)。
  3. 逻辑错误:这些是编译器通常无法捕获的错误(非一错误、不正确的多线程代码等)。静态分析器可能会在这里提供帮助,但这些通常是运行时错误。

@JoshCaswell 在评论中提到了上面的未定义行为——Swift 的一些语义是为了从语言中删除未定义行为而强制执行的规则(如上面的初始化规则)。没有“不安全”模式可以让你关闭这些规则来对 Swift 说“我不关心这些规则的语义”,因为它们是使 Swift 成为它的语言的代码。

我想不出有任何编译器可以 让您在遇到硬错误后继续编译。即使是未定义行为的堡垒 C 和 C++ 也不允许这样做,因为编译过去的错误会将未定义的行为引入 编译器;一旦您尝试编码生成无效的 AST,任何事情都会发生。您可能会得到自相矛盾或毫无意义的程序。就像假设一个错误的陈述是真的可以让你证明任何事情一样,如果你采用无效代码并允许它编译,生成的程序可以做任何数量的完全荒谬的事情。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-03
    • 1970-01-01
    • 2010-09-09
    • 1970-01-01
    • 2017-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多