【问题标题】:Coping with misleading error messages of the Swift compiler (context dependence, type inference)处理 Swift 编译器的误导性错误消息(上下文依赖、类型推断)
【发布时间】:2016-02-12 13:25:27
【问题描述】:

虽然 Swift 编译器 (Xcode 7.2) 在诊断某些与以下内容等效的源文本的错误时似乎完全正确,但检测实际错误需要很长时间。原因:程序员需要看不是标记的文本,而是别处,从而误导,想知道为什么一个可选字符串和一个非可选字符串不能是??的操作数... p>

struct Outer {
    var text : String
}

var     opt : String?
var context : Outer


context = opt ?? "abc"

显然,最后一行应该有context.text 作为要分配的变量。这是诊断:

confusion2.swift:9:19: error: binary operator '??' cannot be applied\
                                to operands of type 'String?' and 'String'
    context = opt ?? "abc"
              ~~~ ^  ~~~~~

消息正式正确。 (我假设检查左侧的类型会为右侧建立一个预期的类型 (Outer),然后,这会使表达式在类型方面不起作用。)不过,从字面上看,诊断是错误的,正如在修复左侧时看到的那样:?? 可以应用于 String? 和 String 类型的操作数。

现在,如果这是最好的,目前,就编译器消息而言,什么是好的应对策略?想起来了

  1. 类型推断!
  2. 上下文!
  3. …

开始?有没有更系统的方法?检查清单?

更新(当答案出现时,我将添加到列表中。谢谢!)

  1. 将语句分开,以便分别检查几行 (@vacawama)
  2. 注意可选项(例如从字典中获取的值),请参阅下面的testSwitchOpt

另一个

enum T {
    case Str(String)
    case Integer(Int)
}

func testSwitchOpt(x : T?) -> Int {
    switch x {
    case .Integer(let r): return r
    default: return 0
    }
}

编译器说

optandswitch.swift:8:15: error: enum case 'Integer' not found in type 'T?'
       case .Integer(let r): return r

解决方法是写switch x!(或更谨慎的let),以便使类型检查地址成为正确的类型,我猜。

我可以,或许应该,向 Apple 提交一些报告,但这个问题似乎代表了一个反复出现的主题——我在其他编译器中看到过这个问题——如果你不这样做,我希望得到一些通用且可重复使用的提示'不介意分享它们。

【问题讨论】:

    标签: xcode swift compiler-errors


    【解决方案1】:

    Swift 的类型推断系统总体上非常出色,但它可能会导致非常混乱的完全错误的错误消息。

    当您收到其中一条毫无意义的 Swift 错误消息时,一个好的策略是将行分成几部分。这将允许 Swift 在错误路径走得太远之前返回更好的错误消息。

    例如,在你的情况下,如果你引入一个临时变量,真正的问题就变得清晰了:

    // context = opt ?? "abc"
    let temp = opt ?? "abc"
    context = temp
    

    现在错误信息如下:

    无法将“String”类型的值分配给“Outer”类型

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-09-18
      • 1970-01-01
      • 1970-01-01
      • 2015-10-03
      • 2019-12-05
      • 2020-01-30
      • 1970-01-01
      相关资源
      最近更新 更多