"++"和" - "运算符已弃用Xcode 7.3

Ole*_*huk 136 increment decrement swift swift2 swift3

我正在看Xcode 7.3笔记,我注意到了这个问题.

++和 - 运算符已被弃用

有人可以解释为什么它被弃用了吗?我是对的,在Xcode的新版本中,你现在要使用而不是++这个x += 1;

例:

for var index = 0; index < 3; index += 1 {
    print("index is \(index)")
}
Run Code Online (Sandbox Code Playgroud)

警告的屏幕截图

Cod*_*ent 205

一个在这里充分说明,从克里斯·拉特纳,斯威夫特的创造者.我将总结一下要点:

  1. 这是学习Swift时必须学习的另一项功能
  2. 不比短得多 x += 1
  3. 斯威夫特不是C.不应该只是为了取悦C程序员
  4. 它的主要用途是C风格的循环:for i = 0; i < n; i++ { ... }Swift有更好的选择,比如for i in 0..<n { ... }(C风格的循环也是如此)
  5. 可能会非常棘手阅读和维护,用于例如,什么是价值x - ++x还是foo(++x, x++)
  6. 克里斯拉特纳不喜欢它.

对于那些感兴趣的人(并避免链接腐烂),Lattner用他自己的话说的理由是:

  1. 这些运算符增加了将Swift作为第一种编程语言学习的负担 - 或者您不熟悉其他语言的这些运算符的任何其他情况.

  2. 它们的表现优势很小 - x ++并不比x + = 1短.

  3. Swift已经偏离C,因为=,+ =和其他类似赋值的操作返回Void(由于多种原因).这些运算符与该模型不一致.

  4. Swift具有强大的功能,消除了在其他语言的C风格循环中使用++ i的许多常见原因,因此这些在编写良好的Swift代码中相对较少使用.这些功能包括for-in循环,范围,枚举,地图等.

  5. 实际使用这些运算符的结果值的代码通常会让代码的读者/维护者感到困惑和微妙.他们鼓励"过于棘手"的代码,这些代码可能很可爱,但很难理解.

  6. 虽然Swift具有良好定义的评估顺序,但任何依赖于它的代码(如foo(++ a,a ++))都是不可取的,即使它是明确定义的.

  7. 这些运算符适用于相对较少的类型:整数和浮点标量,以及类似迭代器的概念.它们不适用于复数,矩阵等.

最后,这些失败的指标"如果我们还没有这些,我们会将它们添加到Swift 3吗?"

  • 我的事,真正的答案是6号.没关系,我们(前C,Java,......程序员)足够灵活:-).通常,对于现实世界,突变,交叉和选择就足够了.我,你和克里斯,我们都是这三家运营商的成果...... (53认同)
  • 这是因为苹果喜欢强迫你像他们一样思考.我认为它完全没问题,可以在需要增加或删除变量的任何地方使用.这不是你"必须学习"的东西,没有它你会做得很好.#5是编写得很糟糕的代码,我从未见过这些代码.所以#6就是这样.解冻它足以让我抓挠我的头并进行谷歌搜索,所以谢谢你浪费我的时间克里斯. (7认同)
  • 第5点:那些总是依赖于实现的C语言,没有任何一个人有任何意义.只需定义行为,我们就会习惯它.最好不得不回去改变完美的旧代码而不是真正的原因. (5认同)
  • @ csga5000考虑到如果你真的想要自己定义运算符,这是一个相当弱的论点.这与苹果希望人们像他们一样思考无关.它根本不适合这种语言.如果在C风格的语言中不存在`++`,那么正确的思维中没有人会看到Swift 3.0的设计,并认为`++`运算符是一个很好的补充. (4认同)
  • 我喜欢第3点.你不能永远被束缚于遗产合同.我喜欢C,但你正在创造一种新的编程语言; 有条不紊地从平板开始,就像你需要它一样干净. (3认同)
  • @overactor首先,我提出了反对所有观点的论据,你选择了一个项目并将其称为弱论点.当然你可以定义运算符,但我认为这不是一个好习惯.它可能会对项目中的其他开发人员造成更大的混淆.我最大的争论是故意*删除*以前存在的功能并达到合理的目的是毫无意义地造成轻微的混乱,让我这样的人花费几分钟的时间. (2认同)
  • 有一个:`for i in(0 .. <n).reverse(){...}` (2认同)
  • 克里斯拉特纳不喜欢它。:D (2认同)
  • 那些疯狂的苹果公司正在删除有用的功能,比如"++"运算符和来自宗派意识形态的耳机插孔.我没有看到Java和C#背后的人删除"++"运算符,他们有更多的常识. (2认同)

010*_*101 36

我知道这评论不回答这个问题仍然有可能是人们寻找一个解决方案如何使这些运营商合作,这样的解决方案可以在底部找到.

我个人更喜欢++--运营商.我不能同意这样的观点,即它们很棘手或难以管理.一旦开发人员了解了这些操作符的作用(我们谈论的是非常简单的东西),代码应该非常清楚.

在解释为什么运营商被弃用时,提到他们的主要用途是C风格的循环.我不了解其他人,但我个人根本不使用C风格的循环,还有很多其他的地方或情况,++或者--运营商是有用的.

我还想提一下,它varName++返回一个值,因此它可以用于returnvarName += 1不能.

对于任何想要让这些运营商在这里工作的人来说,解决方案是:

prefix operator ++ {}
postfix operator ++ {}

prefix operator -- {}
postfix operator -- {}


// Increment
prefix func ++(inout x: Int) -> Int {
    x += 1
    return x
}

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

prefix func ++(inout x: UInt) -> UInt {
    x += 1
    return x
}

postfix func ++(inout x: UInt) -> UInt {
    x += 1
    return (x - 1)
}

prefix func ++(inout x: Int8) -> Int8 {
    x += 1
    return x
}

postfix func ++(inout x: Int8) -> Int8 {
    x += 1
    return (x - 1)
}

prefix func ++(inout x: UInt8) -> UInt8 {
    x += 1
    return x
}

postfix func ++(inout x: UInt8) -> UInt8 {
    x += 1
    return (x - 1)
}
prefix func ++(inout x: Int16) -> Int16 {
    x += 1
    return x
}

postfix func ++(inout x: Int16) -> Int16 {
    x += 1
    return (x - 1)
}

prefix func ++(inout x: UInt16) -> UInt16 {
    x += 1
    return x
}

postfix func ++(inout x: UInt16) -> UInt16 {
    x += 1
    return (x - 1)
}

prefix func ++(inout x: Int32) -> Int32 {
    x += 1
    return x
}

postfix func ++(inout x: Int32) -> Int32 {
    x += 1
    return (x - 1)
}

prefix func ++(inout x: UInt32) -> UInt32 {
    x += 1
    return x
}

postfix func ++(inout x: UInt32) -> UInt32 {
    x += 1
    return (x - 1)
}

prefix func ++(inout x: Int64) -> Int64 {
    x += 1
    return x
}

postfix func ++(inout x: Int64) -> Int64 {
    x += 1
    return (x - 1)
}

prefix func ++(inout x: UInt64) -> UInt64 {
    x += 1
    return x
}

postfix func ++(inout x: UInt64) -> UInt64 {
    x += 1
    return (x - 1)
}

prefix func ++(inout x: Double) -> Double {
    x += 1
    return x
}

postfix func ++(inout x: Double) -> Double {
    x += 1
    return (x - 1)
}

prefix func ++(inout x: Float) -> Float {
    x += 1
    return x
}

postfix func ++(inout x: Float) -> Float {
    x += 1
    return (x - 1)
}

prefix func ++(inout x: Float80) -> Float80 {
    x += 1
    return x
}

postfix func ++(inout x: Float80) -> Float80 {
    x += 1
    return (x - 1)
}

prefix func ++<T : _Incrementable>(inout i: T) -> T {
    i = i.successor()
    return i
}

postfix func ++<T : _Incrementable>(inout i: T) -> T {
    let y = i
    i = i.successor()
    return y
}

// Decrement
prefix func --(inout x: Int) -> Int {
    x -= 1
    return x
}

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

prefix func --(inout x: UInt) -> UInt {
    x -= 1
    return x
}

postfix func --(inout x: UInt) -> UInt {
    x -= 1
    return (x + 1)
}

prefix func --(inout x: Int8) -> Int8 {
    x -= 1
    return x
}

postfix func --(inout x: Int8) -> Int8 {
    x -= 1
    return (x + 1)
}

prefix func --(inout x: UInt8) -> UInt8 {
    x -= 1
    return x
}

postfix func --(inout x: UInt8) -> UInt8 {
    x -= 1
    return (x + 1)
}
prefix func --(inout x: Int16) -> Int16 {
    x -= 1
    return x
}

postfix func --(inout x: Int16) -> Int16 {
    x -= 1
    return (x + 1)
}

prefix func --(inout x: UInt16) -> UInt16 {
    x -= 1
    return x
}

postfix func --(inout x: UInt16) -> UInt16 {
    x -= 1
    return (x + 1)
}

prefix func --(inout x: Int32) -> Int32 {
    x -= 1
    return x
}

postfix func --(inout x: Int32) -> Int32 {
    x -= 1
    return (x + 1)
}

prefix func --(inout x: UInt32) -> UInt32 {
    x -= 1
    return x
}

postfix func --(inout x: UInt32) -> UInt32 {
    x -= 1
    return (x + 1)
}

prefix func --(inout x: Int64) -> Int64 {
    x -= 1
    return x
}

postfix func --(inout x: Int64) -> Int64 {
    x -= 1
    return (x + 1)
}

prefix func --(inout x: UInt64) -> UInt64 {
    x -= 1
    return x
}

postfix func --(inout x: UInt64) -> UInt64 {
    x -= 1
    return (x + 1)
}

prefix func --(inout x: Double) -> Double {
    x -= 1
    return x
}

postfix func --(inout x: Double) -> Double {
    x -= 1
    return (x + 1)
}

prefix func --(inout x: Float) -> Float {
    x -= 1
    return x
}

postfix func --(inout x: Float) -> Float {
    x -= 1
    return (x + 1)
}

prefix func --(inout x: Float80) -> Float80 {
    x -= 1
    return x
}

postfix func --(inout x: Float80) -> Float80 {
    x -= 1
    return (x + 1)
}

prefix func --<T : BidirectionalIndexType>(inout i: T) -> T {
    i = i.predecessor()
    return i
}

postfix func --<T : BidirectionalIndexType>(inout i: T) -> T {
    let y = i
    i = i.predecessor()
    return y
}
Run Code Online (Sandbox Code Playgroud)

  • 你也可以使用`defer`.`defer {x + = 1}; 返回x` (3认同)
  • 我不喜欢你对后缀运算符的“return (x - 1)” - 恕我直言,维护它们返回(原始值的副本)的语义比执行“x + 1”时得到的语义更清晰 - 1` (2认同)
  • 为什么不使用泛型并将其写成几行呢? (2认同)

Soh*_*mon 22

苹果已经删除++了它,并使用另一种传统的旧方式使其变得更加简单.

而不是++,你需要写+=.

例:

var x = 1

//Increment
x += 1 //Means x = x + 1 
Run Code Online (Sandbox Code Playgroud)

类似地,对于递减运算符--,您需要编写-=

例:

var x = 1

//Decrement
x -= 1 //Means x = x - 1
Run Code Online (Sandbox Code Playgroud)

For for循环:

增量示例:

代替

for var index = 0; index < 3; index ++ {
    print("index is \(index)")
}
Run Code Online (Sandbox Code Playgroud)

你可以写:

//Example 1
for index in 0..<3 {
    print("index is \(index)")
}

//Example 2
for index in 0..<someArray.count {
    print("index is \(index)")
}

//Example 3
for index in 0...(someArray.count - 1) {
    print("index is \(index)")
}
Run Code Online (Sandbox Code Playgroud)

减量示例:

for var index = 3; index >= 0; --index {
   print(index)
}
Run Code Online (Sandbox Code Playgroud)

你可以写:

for index in 3.stride(to: 1, by: -1) {
   print(index)
}
//prints 3, 2

for index in 3.stride(through: 1, by: -1) {
   print(index)
}
//prints 3, 2, 1

for index in (0 ..< 3).reverse() {
   print(index)
}

for index in (0 ... 3).reverse() {
   print(index)
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!

  • 那么`++ i`和`--i`怎么样? (3认同)
  • 他们没有更换任何东西;`+=` 一直存在。 (2认同)

Jay*_*hta 8

克里斯拉特纳已经开始对抗++和 - .他写道,"实际使用这些运算符的结果值的代码通常会让代码的读者/维护者感到困惑和微妙.他们鼓励"过于棘手"的代码,这些代码可能很可爱但很难理解......虽然Swift有很好的定义评估顺序,任何依赖它的代码(如foo(++ a,a ++))都是不可取的,即使它定义明确......这些失败的指标"如果我们还没有这些,我们会将它们添加到Swift 3吗?"

Apple希望尽快保持干净,清晰,不混淆且直截了当的语言.所以他们弃用了++和 - keyword.

  • 类似于`... for i in 0.stride(to:10,by:2)...`或`... for i in(1 ... 10).reverse()...`is clean ?! (21认同)
  • 清洁?看看这个回调地狱并称之为干净?我不同意......而且我补充说:只留下++和 - (9认同)
  • 我同意.对于斯威夫特的其他人来说,"干净"的论点与根本上是矛盾的.来自Objective-C,客观上是不洁净的,很难接受'干净'作为Apple的语言目标. (5认同)
  • 尝试解析json和swift并告诉我它有多干净. (2认同)

小智 7

对于 Swift 4,您可以将++and--运算符恢复为Intand 其他类型的扩展。下面是一个例子:

extension Int{
   static prefix func ++(x: inout Int) -> Int {
        x += 1
        return x
    }

    static postfix func ++(x: inout  Int) -> Int {
        defer {x += 1}
        return x
    }

    static prefix func --(x: inout Int) -> Int {
        x -= 1
        return x
    }

    static postfix func --(x: inout Int) -> Int {
        defer {x -= 1}
        return x
    }
}
Run Code Online (Sandbox Code Playgroud)

对于其他类型,如、、、 等UIInt,它的工作方式相同。Int8FloatDouble

您可以将这些扩展名粘贴到根目录中的单个文件中,它们将可供您在那里的所有其他文件中使用。如果您在操场上查看它,它可以完美运行。


Jay*_*bey 6

警告的屏幕截图

Fix-it featureXcode中的提供了明确的答案.

警告解决方案

更换++ increment operator用老式的value += 1(短手操作),并-- decrement operatorvalue -= 1


小智 5

这是迄今为止发布的一些代码的通用版本。我会表达与其他人相同的担忧:最好不要在 Swift 中使用这些。我同意这可能会让将来阅读您的代码的人感到困惑。

prefix operator ++
prefix operator --
prefix func ++<T: Numeric> (_ val: inout T) -> T {
    val += 1
    return val
}

prefix func --<T: Numeric> (_ val: inout T) -> T {
    val -= 1
    return val
}

postfix operator ++
postfix operator --
postfix func ++<T: Numeric> (_ val: inout T) -> T {
    defer { val += 1 }
    return val
}

postfix func --<T: Numeric> (_ val: inout T) -> T {
    defer { val -= 1 }
    return val
}
Run Code Online (Sandbox Code Playgroud)

这也可以写成 Numeric 类型的扩展。