我正在查看Xcode 7.3说明,我注意到了这个问题。
已弃用++和 - 运算符
有人可以解释为何弃用它吗?我是对的,现在你要使用新版本的Xcode而不是++
这个x += 1
;
示例:
for var index = 0; index < 3; index += 1 {
print("index is \(index)")
}
答案 0 :(得分:201)
来自斯威夫特创作者克里斯拉特纳的full explanation here。我将总结一下要点:
x += 1
for i = 0; i < n; i++ { ... }
,Swift有更好的选择,比如for i in 0..<n { ... }
(循环的C风格是going out as well)x - ++x
或foo(++x, x++)
的价值是多少?对于那些感兴趣的人(并避免链接腐烂),Lattner用他自己的话说的理由是:
这些运算符增加了学习Swift作为第一种编程语言的负担 - 或任何其他你不熟悉不同语言的运算符的情况。
他们的表现优势很小 - x ++并不比x + = 1短。
Swift已经偏离C,因为=,+ =和其他类似赋值的操作返回Void(由于多种原因)。这些操作符与该模型不一致。
Swift具有强大的功能,消除了在其他语言的C风格循环中使用++ i的许多常见原因,因此这些在编写良好的Swift代码中相对较少使用。这些功能包括for-in循环,范围,枚举,地图等。
实际使用这些运算符的结果值的代码通常会让代码的读者/维护者感到困惑和微妙。他们鼓励“过于棘手”的代码,这些代码可能很可爱,但很难理解。
虽然Swift具有良好定义的评估顺序,但任何依赖它的代码(如foo(++ a,a ++))都是不受欢迎的,即使它是明确定义的。
- 醇>
这些运算符适用于相对较少的类型:整数和浮点标量,以及类似迭代器的概念。它们不适用于复数,矩阵等。
最后,这些指标未能通过“如果我们还没有这些,我们会将它们添加到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)
Xcode的CREATE PROCEDURE [dbo].[InsertTelemetryData]
@MessageTVP AS MessageTVP READONLY,
@ExceptionTVP AS ExceptionTVP READONLY
给出了明确的答案。
将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
}
}
其他类型的工作方式相同,例如UIInt
,Int8
,Float
,Double
等。
您可以将这些扩展名粘贴到根目录中的单个文件中,并且可以在其中的所有其他文件中使用它们。
我已经注意到我的答案在我发布的时候差不多了。我认为这是一种哲学上的分歧,而不是对我的代码如何运作的批评。如果你在操场上看看,它的效果非常好。
我之所以发布这个答案,是因为我不同意使计算机编程语言彼此不必要的不同。
语言之间有很多相似之处,因此人们可以更轻松地学习和从一种语言切换到另一种语言。
开发人员通常使用多种编程语言,而不只是一种。当没有惯例并且没有跨语言的共同标准化时,从一种语言切换到另一种语言真的很麻烦。
我认为语言之间只有必要的语法差异,而不仅仅是这个。
答案 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
,这是最重要的一点。因此,++i
和i++
也返回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,他们肯定会关闭他们的业务理解,在这一点上,他们无法及时赶上。