如您所知,Swift可以根据使用情况推断类型。例如,您可以有仅在返回类型上不同的重载方法,并且只要编译器能够推断类型,就可以自由使用它们。例如,通过帮助额外显式类型变量来保存此类方法的返回值。
我发现了一些有趣的时刻。想象一下这个类:
class MyClass {
enum MyError: Error {
case notImplemented
case someException
}
func fun1() throws -> Any {
throw MyError.notImplemented
}
func fun1() -> Int {
return 1
}
func fun2() throws -> Any {
throw MyError.notImplemented
}
func fun2() throws -> Int {
if false {
throw MyError.someException
} else {
return 2
}
}
}
当然,它会像这样工作:
let myClass = MyClass()
// let resul1 = myClass.fun1() // error: ambiguous use of 'fun1()'
let result1: Int = myClass.fun1() // OK
但是接下来你可以写类似这样的内容:
// print(myClass.fun1()) // error: call can throw but is not marked with 'try'
// BUT
print(try? myClass.fun1()) // warning: no calls to throwing functions occur within 'try' expression
看起来像是互斥的语句。编译器试图选择正确的函数;在第一次调用时,它试图将Int强制转换为Any,但在第二个语句中它试图做什么呢?
此外,像下面这样的代码
if let result2 = try? myClass.fun2() { // No warnings
print(result2)
}
没有警告,因此可以假设编译器能够在这里选择正确的重载(也许基于一个事实,即其中一个重载实际上什么都不返回,只是抛出异常)。
我的最后一种假设正确吗?对于 fun1()
的警告是否合理?我们有一些技巧可以欺骗编译器或帮助它进行类型推断吗?
@warn_unused_result
吗?(但我以为现在已经默认了?) - Rob Napier