++ 在 Swift 中到底是什么意思?

what does ++ exactly mean in Swift?

我正在学习 Swift 一本针对经验不足的人的书。困扰我的一件事是 ++ 语法。以下内容摘自书中:

var counter = 0
let incrementCounter = {
  counter++
}
incrementCounter()
incrementCounter()
incrementCounter()
incrementCounter()
incrementCounter()

书上说计数器是5。

但我是在 Xcode 操场上输入这些代码的。是4个!

我很困惑。

x++运算符是一种在多种语言中使用的运算符——C、C++、Java(参见C answer同一个问题)

叫做post-增量。它将给定变量递增 1,但在计算当前表达式之后。例如:

var x = 1
var y = 2 + x++
// the value of x is now 2 (has been incremented)
// the value of y is now 3 (2 + 1, x has been evaluated before increment)

这与 ++x(预递增)运算符不同:

var x = 1
var y = 2 + ++x
// the value of x is now 2 (has been incremented)
// the value of y is now 4 (2 + 4, x has been evaluated after increment)

请注意,运算符 将在 Swift 的下一版本中删除,因此您不应再使用它。

最好只写 x += 1 而不是有副作用的复杂表达式。

post-递增和post-递减运算符将其操作数的值增加(或减少)1,但表达式的值是操作数在递增之前的原始值(或递减)操作

因此,当您看到 playground 时,正在打印计数器的当前值。

但是在计算函数之后,计数器的值发生了变化,您可以在下一行看到更新后的值。

五次调用 incrementCounter 闭包后 counter 的值将为 5,但 return每次调用 incrementCounter 似乎都会 "lag" 落后一步。正如 Sulthan 在他的回答中所写,这是由于 x++ 是一个 post 递增运算符:表达式的结果将是 returned prior 递增

var x = 0
print(x++) // 0
print(x)   // 1

此外,正如我在上面的评论中所写,您不应使用 ++-- 运算符,因为它们将是 deprecated in Swift 2.2 and removed in Swift 3。但是,如果您对 post- 与预递增运算符的详细信息感兴趣,您可以在 SO 标记为其他语言的此处找到很好的答案,但涵盖相同的主题,例如

  • What is the difference between ++i and i++?

然而,值得一提的是, 与 Swift > 2.1 相关,但与++ 运算符。

当您启动关闭时 incrementCounter 作为

var someOne : Int = 0
let incrementCounter = {
    someInt
}

闭包被隐式推断为 () -> Int 类型:一个采用零参数但具有 Int.

类型的单个 return 的闭包
let incrementCounter: () -> Int = {
    return someInt
}

因此,您在操场上看似 "see" 的是 [=14= 调用的未使用(未分配)return 值] 关闭;即表达式 incrementCounter().

的结果

counter 的值从来没有真正打印在你的 playground 的右边块中(除非你写了一行 line:s 表达式的结果是 counter)。

你正在做的事情是post增量。

先了解Pre和PostIncrement的区别

  1. 在Post增量中,增量后的数值计数器包含增量值 (即5) 但是如果我们 return,那么它将包含 旧值 (即 4).
  2. 在Pre Increment中,值和return值都会递增。

现在让我们看看您的代码,

counter++ 制作副本,增加计数器,return 复制副本(旧值)。

所以如果你打印 counter 它将增加值 (即 5) 但是,如果您 return 计数器 (即您使用 incrementCounter 这样做) 它包含旧值 (即 4).

因为 incrementCounter 最多只显示 4.

检查输出 解决方案:

counter++ 更改为 ++counter

检查输出

尽管有很多答案而且所有答案都很清楚,但我还是添加了这个片段来向您展示如何用 'new' 语法替换您的代码,其中 ++ 和 or -- 已被弃用。首先你自己的代码

var counter = 0
let incrementCounter = {
    counter++
}
let i0 = incrementCounter() // 0
let i1 = incrementCounter() // 1
// .....

以后如何重写Swift的语法?让我们尝试推荐的替代品 ...

var counter = 0
let ic = {
    counter += 1
}
let i0 = ic() // () aka Void !!!
let i1 = ic() // ()

但现在 ic() 的结果是 Void!嗯...好的,下一次尝试可能看起来像

var counter = 0
let ic = {
    counter += 1
    return counter
}

但是现在代码没有编译错误:无法推断当前上下文中的闭包 return 类型 :-),所以我们必须声明它(在我们的原始版本中没有必要)

var counter = 0
let ic:()->Int = {
    counter += 1
    return counter
}
let i0 = ic() // 1
let i1 = ic() // 2
// .....

有效,但结果不一样。那是因为在原始代码中 ++ 运算符被用作 post-increment 运算符。所以,我们需要对 'new' 版本

进行另一次调整
var counter = 0
let ic:()->Int = {
    let ret = counter
    counter += 1
    return ret
}
let i0 = ic() // 0
let i1 = ic() // 1
// .....

是的,我希望看到我熟悉的一元 ++ 和/或 -- 也会出现在 Swift

的未来版本中

++ 和 -- 在标识符 add/subtract 之前,然后是 return 它的值。
++ 和 -- 在标识符 return 其值之后,然后是 add/subtract 1.

They were removed 在 Swift 3.0 中,但您可以将它们添加回去:

prefix operator --
prefix operator ++
postfix operator --
postfix operator ++

prefix func ++(_ a : inout Int) -> Int {
    a += 1
    return a
}
prefix func --(_ a : inout Int) -> Int {
    a -= 1
    return a
}
postfix func ++(_ a: inout Int) -> Int {
    defer { a += 1 }
    return a
}
postfix func --(_ a: inout Int) -> Int {
    defer { a -= 1 }
    return a
}

var a = 11
print(a++) // 11
print(a)   // 12

var b = 5
print(--b) // 4
print(b) // 4