Swift reduce - 为什么值是可选的?

Swift reduce - why is value optional?

为什么 total 在行 return total + 1 上是可选的?

return first.enumerated().reduce(0) { total, letter in
   let index = first.index(first.startIndex, offsetBy: letter.offset)
   if first[index] != second[index]{
       return total + 1
   }
   return total
}

Value of optional type 'Int?' must be unwrapped to a value of type'Int' Coalesce using '??' to provide a default when the optional value contains 'nil' Force-unwrap using '!' to abort execution if the optional value contains 'nil'

所以这修复了它:

return first.enumerated().reduce(0) { total, letter in
   let index = first.index(first.startIndex, offsetBy: letter.offset)
   if first[index] != second[index]{
       return total! + 1
   }
   return total
}

如果我分解它,添加 let index 时会发生变化......

OK - 这个 returns first 和 total 的总计数不是可选的:

return first.reduce(0) { total, letter in
    return total + 1
}

确定 - 此枚举和总计不是可选的:

return first.enumerated().reduce(0) { total, letter in
    return total + 1
}

错误 - 这得到一个编译错误,总计是可选的

return first.enumerated().reduce(0) { total, letter in
    let index = first.index(first.startIndex, offsetBy: letter.offset)
    return total + 1
}

为了让您得到这个结果(据我所知),封闭函数必须 return 和 Int?。言外之意就是 reduce 可以 return 一个可选的。如果没有条件,编译器可以确定 reduce 永远不会 return nil,即 total 永远不会为 nil。因此,编译器推断闭包的 return 类型是 Int。编译器似乎正在纠缠 reduce 闭包和 total 的类型推断。添加条件后,编译器无法确定 reduce 是否会 return nil。现在,当它不必要地推断 total 的类型时,它就出错了。

对我来说,这看起来像是 Swift 类型推断误入歧途的情况。显然,根据 enumerated.

的文档,total 永远不会为零

如果您稍微修改一下代码,您会得到预期的结果:

   return first.enumerated().reduce(0) { (total: Int, letter) in
       let index = first.index(first.startIndex, offsetBy: letter.offset)
       if first[index] != second[index]{
          return total + 1
       }
       return total
   }

Swift 进行了很多类型推断,这真的很棒,因为我在保留动态语言的许多优点的同时获得了强类型。然而,根据我的经验,swift 的推论有时会令人费解。它可以轻松处理神秘情况,并在我认为显而易见的事情上绊倒。

我觉得这像是一个错误。