“++”和“ - ”运算符已弃用Xcode 7.3

时间:2016-02-02 16:14:30

标签: swift swift2 increment swift3 decrement

我正在查看Xcode 7.3说明,我注意到了这个问题。

  

已弃用++和 - 运算符

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

示例:

for var index = 0; index < 3; index += 1 {
    print("index is \(index)")
}

Screenshot for warning

12 个答案:

答案 0 :(得分:201)

来自斯威夫特创作者克里斯拉特纳的full explanation here。我将总结一下要点:

  1. 这是学习Swift时必须学习的另一项功能
  2. 不比x += 1
  3. 斯威夫特不是C.不应该只是为了取悦C程序员
  4. 它的主要用途是C风格的循环:for i = 0; i < n; i++ { ... },Swift有更好的选择,比如for i in 0..<n { ... }(循环的C风格是going out as well
  5. 阅读和维护可能很棘手,例如,x - ++xfoo(++x, x++)的价值是多少?
  6. Chris Lattner不喜欢它。
  7. 对于那些感兴趣的人(并避免链接腐烂),Lattner用他自己的话说的理由是:

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

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

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

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

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

    10.   
    11. 虽然Swift具有良好定义的评估顺序,但任何依赖它的代码(如foo(++ a,a ++))都是不受欢迎的,即使它是明确定义的。

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

    14.         

      最后,这些指标未能通过“如果我们还没有这些,我们会将它们添加到Swift 3吗?”

答案 1 :(得分:34)

我意识到这条评论并没有回答这个问题,但是可能有人在寻找解决方案如何让这些运算符保持正常工作,这样的解决方案可以在底部找到。 < / p>

我个人更喜欢++--运营商。我不同意他们认为棘手或难以管理的观点。一旦开发人员了解了这些操作符的作用(我们正在讨论非常简单的东西),代码应该非常清楚。

在解释为什么弃用运算符时,提到它们的主要用途是C风格的循环。我不了解其他人,但我个人根本不使用C风格的循环,当++--运算符有用时,仍有许多其他地方或情况。< / p>

我还想提一下,varName++会返回一个值,因此可以在return中使用,而varName += 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
}

答案 2 :(得分:22)

Apple删除了if len(sys.argv) > 1: ,并用另一种古老的传统方式使其变得更加简单。

而不是++,您需要编写++

示例:

+=

对于递减运算符var x = 1 //Increment x += 1 //Means x = x + 1 ,您需要编写--

示例:

-=

对于var x = 1 //Decrement x -= 1 //Means x = x - 1 循环:

增量示例:

而不是

for

您可以写:

for var index = 0; index < 3; index ++ {
    print("index is \(index)")
}

减量示例:

//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)")
}

您可以写:

for var index = 3; index >= 0; --index {
   print(index)
}

希望这有帮助!

答案 3 :(得分:8)

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

Apple希望迅速保持清晰,清晰,不混淆且直截了当的语言。所以他们弃用了++和 - keyword。

答案 4 :(得分:6)

Screenshot for warning

Xcode的CREATE PROCEDURE [dbo].[InsertTelemetryData] @MessageTVP AS MessageTVP READONLY, @ExceptionTVP AS ExceptionTVP READONLY 给出了明确的答案。

Solution to warning

Fix-it feature替换为旧式++ increment operator(简写操作符),将value += 1替换为-- decrement operator

答案 5 :(得分:4)

来自docs

  

Swift中的增量/减量运算符很早就被添加了   Swift的发展,作为C的结转。这些都被添加了   没有多少考虑,自那以后就没有多想过了   然后。本文档最后对它们进行了全新的介绍   建议我们完全删除它们,因为它们令人困惑   没有承受重量。

答案 6 :(得分:3)

对于Swift 4,您可以将++--运算符还原为Int和其他类型的扩展名。这是一个例子:

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
    }
}

其他类型的工作方式相同,例如UIIntInt8FloatDouble等。

您可以将这些扩展名粘贴到根目录中的单个文件中,并且可以在其中的所有其他文件中使用它们。

我已经注意到我的答案在我发布的时候差不多了。我认为这是一种哲学上的分歧,而不是对我的代码如何运作的批评。如果你在操场上看看,它的效果非常好。

我之所以发布这个答案,是因为我不同意使计算机编程语言彼此不必要的不​​同。

语言之间有很多相似之处,因此人们可以更轻松地学习和从一种语言切换到另一种语言。

开发人员通常使用多种编程语言,而不只是一种。当没有惯例并且没有跨语言的共同标准化时,从一种语言切换到另一种语言真的很麻烦。

我认为语言之间只有必要的语法差异,而不仅仅是这个。

答案 7 :(得分:0)

这里是到目前为止发布的某些代码的通用版本。我会与其他人表达相同的担忧:最好不要在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
}

这也可以写为数字类型的扩展名。

答案 8 :(得分:0)

由于您从未真正在Swift中使用过指针,因此我认为删除++--运算符是很有意义的。但是,如果您不能没有,可以将以下 Swift 5 + 运算符声明添加到您的项目中:

@discardableResult
public prefix func ++<T: Numeric>(i: inout T) -> T {
    i += 1
    return i
}

@discardableResult
public postfix func ++<T: Numeric>(i: inout T) -> T {
    defer { i += 1 }
    return i
}

@discardableResult
public prefix func --<T: Numeric>(i: inout T) -> T {
    i -= 1
    return i
}

@discardableResult
public postfix func --<T: Numeric>(i: inout T) -> T {
    defer { i -= 1 }
    return i
}

答案 9 :(得分:-1)

var value : Int = 1

func theOldElegantWay() -> Int{
return value++
}

func theNewFashionWay() -> Int{
let temp = value
value += 1
return temp
}

这绝对是一个缺点,对吧?

答案 10 :(得分:-1)

i += 1返回Void,这是最重要的一点。因此,++ii++也返回Void。它们将保持相同的含义。这时,您将了解删除它会更好,就像Python一样。

答案 11 :(得分:-2)

在Swift 4.1中,可以通过这种方式实现:



    prefix operator ++
    postfix operator ++
    extension Int{
        static prefix func ++(x: inout Int)->Int{
            x += 1
            return x
        }
        static postfix func ++(x: inout Int)->Int{
            x += 1
            return x-1
        }
    }
    //example:
    var t = 5
    var s = t++
    print("\(t) \(s)")


请注意,尽管此解决方案与此帖中的先前解决方案类似,但它们在Swift 4.1中不再起作用,此示例也是如此。 还要注意上面提到的那些+ =是++的替代品,但是不完全理解操作符,因为++与赋值相结合实际上是两个操作,因此是一个捷径。 在我的例子中:var s = t++做了两件事:将t的值赋给s然后递增t。如果之前是++,那么它是以相反的顺序完成的相同的两个操作。 在我看来,Apple关于为什么删除这个运算符(在前面的答案中提到)的推理不仅是错误的推理,而且我认为这是一个谎言,真正的原因是他们无法使他们的编译器处理它。它给了他们以前版本的麻烦,所以他们放弃了。 &#34;逻辑太复杂,无法理解运算符,因此删除了&#34;显然是一个谎言,因为Swift包含的操作符要复杂得多,而且没有被删除。此外,绝大多数编程语言都有它。 JavaScript,C,C#,Java,C ++等等。程序员愉快地使用它。 无论谁理解这个算子都太难了,他们只有他们应该做+ =(或者如果+ =太复杂也可能s = s + 1)。

Swift背后的策略很简单:Apple认为程序​​员是愚蠢的,因此应该得到相应的处理。

事实是,2014年9月推出的Swift现在应该是其他地方。其他语言的成长速度要快得多。

我可以列出语言中的许多重大错误,从严重的错误:例如按值而不是通过引用粘贴的数组,到烦人的错误:变量参数函数不能接受一个数组,这是它背后的整个想法。 我不认为Apple的员工甚至被允许查看Java等其他语言,因此他们甚至不知道Apple落后了几年。 Apple本可以采用Java作为一种语言,但现在,挑战不是技术,而是自我。 如果他们打开IntelliJ来编写一些Java,他们肯定会关闭他们的业务理解,在这一点上,他们无法及时赶上。