Swift 具有隐式解包可选的一元运算符

Swift unary operator with implicitly unwrapped optional

所以我问了,好像是这个原因

var num:Int! = 0
num++

不起作用是因为 ++ 运算符采用 inout 参数,而隐式展开的可选参数则不是。然而,在

var num:Int! = 0
num = num + 1

+ 运算符与隐式解包可选一起使用,这意味着二元运算符 不需要 需要 inout 参数。所以我的问题是,为什么一元和二元运算符有不同的参数要求?仅对二元运算符使用 Int!,但对所有内容都使用 Int,这对我来说似乎有点傻。

why do unary and binary operators have different parameter requirements?

好吧,这不是一元与二元的问题。有与 Int! 一起使用的一元运算符。例如:

var i: Int! = 17
var j = -i

- 是一元运算符,它可以工作。问题又回到了inout的问题上。 Int++ 前缀和后缀运算符不适用于 Int!,因为变量作为 inout 传递(因为 ++ 还修改了原始变量return 一个值)。 inout 要求类型完全匹配。

请注意,隐式展开的可选值仍然是可选值。

var i: Int! = 17
var k = i    // k has the type Int!
var m = i!   // m has the type Int

因此,将隐式展开的可选类型作为需要非可选类型的 inout 变量传递是行不通的,因为 inout 变量需要与预期类型完全匹配,并且 IntInt! 是两种截然不同的类型。该变量必须显式解包,或者您需要提供一个采用可选类型的重载函数。

您可能会问,为什么 Swift 不直接为您打开 Int! 并用 Int 调用 ++?好吧,++ 既修改了变量又 return 修改了一个值。如果 Swift 解包 Int! 并使用 Int 调用 ++,那么 return 的类型将是 Int。然后你会有人在 Whosebug 上问,"why does var i: Int! = 17; var j = i++ make j an Int instead of an Int! ?"。为了正确地做到这一点,++ 需要 return 一个 Int 当它被赋予一个 Int 和 return 一个 Int! 当它被赋予一个 Int!。那么,重载函数需要什么。

可以重载 ++ 并为 Int! 创建 ++ 前缀和后缀函数:

prefix func ++(inout x: Int!) -> Int! {
    return ++x!
}

postfix func ++(inout x: Int!) -> Int! {
    return x!++
}

var i: Int! = 17
var j = ++i
print("i = \(i), j = \(j)")  // "i = 18, j = 18"
j = i++
print("i = \(i), j = \(j)")  // "i = 19, j = 18"

至于为什么Swift设计师没有做到这一点,只有他们知道为什么。