“++”和“--”运算符已被弃用 Xcode 7.3
Posted
技术标签:
【中文标题】“++”和“--”运算符已被弃用 Xcode 7.3【英文标题】:The "++" and "--" operators have been deprecated Xcode 7.3 【发布时间】:2016-05-11 13:12:40 【问题描述】:我正在查看 Xcode 7.3 注释,我注意到了这个问题。
++ 和 -- 运算符已被弃用
有人能解释一下为什么不推荐使用它吗?我对吗,现在在新版本的 Xcode 中你要使用 ++
而不是 x += 1
;
例子:
for var index = 0; index < 3; index += 1
print("index is \(index)")
【问题讨论】:
我认为这个问题如果超出了***的范围主要是因为所有被接受的关于快速进化的提案都可以在Github中找到,你可以阅读更多关于这个提案的原因github.com/apple/swift-evolution/blob/master/proposals/…跨度> 我正在认真考虑回到Objective-C。尝试跟上 Swift 的所有变化是不值得的。 @OlegGordiichuk 这也是 C 风格的 for 循环也将被删除的东西,请参阅此 github.com/Vkt0r/swift-evolution/blob/master/proposals/…,因此您不需要使用更多++
和 --
运算符
我的口味有太多重大变化。我完全赞成改进,但我真的不想在每次 Xcode 点发布时都花时间重写我的代码库的大部分内容。
@Fogmeister 我不确定我怎么能更清楚。我更喜欢使用 Swift,但我觉得它不够稳定。过去我曾与其他语言进行过广泛的合作,并且从未在如此短的时间内遇到如此多的重大变化。我觉得 Apple 希望我们所有人都采用 Swift,但他们让这变得比应有的困难。
【参考方案1】:
来自 Swift 的创造者 Chris Lattner 的full explanation here。我总结一下几点:
-
这是您在学习 Swift 时必须学习的另一个功能
不比
x += 1
短多少
Swift 不是 C。不应该仅仅为了取悦 C 程序员而把它们带过来
它的主要用途是 C 风格的 for 循环:for i = 0; i < n; i++ ...
,Swift 有更好的替代品,比如 for i in 0..<n ...
(C 风格的 for 循环是 going out as well)
可能难以阅读和维护,例如,x - ++x
或 foo(++x, x++)
的值是多少?
Chris Lattner 不喜欢它。
对于那些感兴趣的人(并且为了避免链接失效),Lattner 用他自己的话来说的原因是:
这些运算符增加了将 Swift 作为第一种编程语言学习的负担 - 或者您还不知道这些运算符来自其他语言的任何其他情况。
它们的表达优势很小 - x++ 并不比 x += 1 短很多。
Swift 已经偏离了 C,因为 =、+= 和其他类似赋值的操作返回 Void(出于多种原因)。这些运算符与该模型不一致。
Swift 具有强大的功能,可以消除您在其他语言的 C 风格 for 循环中使用 ++i 的许多常见原因,因此这些在编写良好的 Swift 代码中相对较少使用。这些功能包括 for-in 循环、范围、枚举、映射等。
实际使用这些运算符的结果值的代码通常会使代码的读者/维护者感到困惑和微妙。他们鼓励“过于棘手”的代码,这些代码可能很可爱,但很难理解。
虽然 Swift 有明确定义的求值顺序,但任何依赖于它的代码(如 foo(++a, a++))即使定义明确也是不可取的。
这些运算符适用于相对较少的类型:整数和浮点标量,以及类似迭代器的概念。它们不适用于复数、矩阵等。
最后,这些都没有达到“如果我们还没有这些,我们会将它们添加到 Swift 3 中吗?”这一指标。
【讨论】:
我的意思是,真正的答案是 6 号。没关系,我们(前 C、Java、... 程序员)足够灵活 :-)。一般来说,对于现实世界来说,变异、交叉和选择就足够了。我、你和克里斯也是,我们都是这三个运营商的结果…… 第 5 点:那些在 C 中总是依赖于实现的,没有任何人做过。只需定义行为,我们就会习惯它。总比无缘无故地返回并更改完美的旧代码要好。 我喜欢第 3 点。你不能永远被传统的契约束缚。我喜欢 C 但你正在创建一种新的编程语言;从你需要的干净的石板开始是有意义的。 这是因为苹果喜欢强迫你像他们一样思考。我认为它非常好,可以在需要增加或减少变量的任何地方使用。这不是你“必须学习”的东西,没有它你会做得很好。而#5 只是写得很糟糕的代码,我从未见过这样的代码。所以#6是。贬低它足以让我挠头并进行谷歌搜索,所以感谢克里斯浪费我的时间。 @csga5000 这是一个相当弱的论点,因为如果你真的想的话,你可以自己定义操作符。这与苹果希望人们像他们一样思考无关。它根本不适合这种语言。如果++
不存在于 C 风格的语言中,那么任何头脑正常的人都不会看到 Swift 3.0 的设计并认为 ++
运算符会是一个很好的补充。【参考方案2】:
我意识到这个评论并没有回答这个问题,但是可能有人在寻找如何让这些操作员继续工作的解决方案,这样的解决方案可以在底部找到。 ?
我个人更喜欢++
和--
运算符。我不同意他们棘手或难以管理的观点。一旦开发人员了解了这些运算符的作用(我们谈论的是非常简单的东西),代码应该非常清晰。
在解释为什么不推荐使用运算符时提到它们的主要用途是 C 风格的 for 循环。我不知道其他人,但我个人根本不使用 C 风格的循环,还有很多其他地方或情况 ++
或 --
运算符有用。
我还想提一下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
【讨论】:
我不喜欢你的return (x - 1)
用于后缀运算符 - 恕我直言,维护它们返回(副本)原始值而不是什么的语义更干净如果你这样做,你会得到x + 1 - 1
我也不喜欢它,但我不知道有任何其他(更好、更清洁)的方法。我不完全理解你的第二点。
我明白了,我不想仅仅为了创建另一个变量(或者在这种情况下是常量)而这样做。如果我们只讨论Int
,那么(x + 1)
的结果将被溢出,这将中断执行,因此result - 1
甚至不会被运行。例如,Double
等其他数据类型的行为方式不同,因此我需要对此进行调查。
您也可以为此使用defer
。 defer x += 1 ; return x
为什么不用泛型,用几行代码写出来?【参考方案3】:
Apple 删除了 ++
并使用另一种旧的传统方式使其更简单。
你需要写+=
,而不是++
。
示例:
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)
你可以写:
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)
希望这会有所帮助!
【讨论】:
他们没有更换任何东西;+=
一直都在。
@NicolasMiari 是的,只是用更好的格式编辑
@NicolasMiari 你现在可以检查一下吗?
++i
和 --i
怎么样?【参考方案4】:
对于 Swift 4,您可以将 ++
和 --
运算符恢复为 Int
和其他类型的扩展。这是一个例子:
extension Int
@discardableResult
static prefix func ++(x: inout Int) -> Int
x += 1
return x
static postfix func ++(x: inout Int) -> Int
defer x += 1
return x
@discardableResult
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
等。
您可以将这些扩展粘贴到根目录中的单个文件中,它们将可在您那里的所有其他文件中使用。如果您在操场上查看它,它会完美运行。
【讨论】:
【参考方案5】:Chris Lattner 与 ++ 和 -- 开战。他写道,“实际使用这些运算符的结果值的代码对于代码的读者/维护者来说往往是令人困惑和微妙的。他们鼓励“过于棘手”的代码,这些代码可能很可爱,但难以理解……虽然 Swift 有明确定义的评估顺序,但任何依赖它的代码(如 foo(++a, a++))都是不可取的,即使它是明确定义的……这些没有达到“如果我们还没有这些,我们会将它们添加到 Swift 3 中吗?”的度量标准
Apple 希望保持 swift 是一种干净、清晰、不混淆且直截了当的语言。所以他们弃用了 ++ 和 -- 关键字。
【讨论】:
干净吗?看看这个回调地狱并称其为干净?我不同意...而且我要补充一点:留下 ++ & -- 单独...for i in 0.stride(to: 10, by: 2)...
或 ...for i in (1...10).reverse()...
这样的东西是干净的吗?!
我同意。 “干净”的论点与 Swift 的其余部分根本矛盾。来自客观上不干净的 Objective-C,很难接受“干净”作为 Apple 语言的目标。
尝试解析 json 和 swift 并告诉我它有多干净。【参考方案6】:
Xcode 的Fix-it feature
给出了明确的答案。
将++ increment operator
替换为老式的value += 1
(简写运算符),将-- decrement operator
替换为value -= 1
【讨论】:
【参考方案7】:这是迄今为止发布的一些代码的通用版本。我会表达与其他人相同的担忧:在 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
这也可以写成 Numeric 类型的扩展。
【讨论】:
我在每个函数中添加了@discardableResult
,以消除有关返回值未使用的警告;否则正是我想要的。【参考方案8】:
来自docs:
Swift 中的递增/递减运算符很早就添加了 Swift 的开发,作为 C 的继承。这些被添加 没有太多考虑,从那以后也没有考虑太多 然后。本文档提供了一个全新的视角,并最终 建议我们完全删除它们,因为它们令人困惑并且 没有承受他们的重量。
【讨论】:
也就是说这个操作太贵了不能用? github.com/apple/swift-evolution/blob/master/proposals/… 在这里你可以读到它,但这不是因为它很昂贵,而是因为它的语言设计。 所以我安徒生 Swift 将放弃对 C 风格特性的支持 @OlegGordiichuk 好吧,我想说他们想强调的是,与 Objective-C 不同,Swift 不是 C 的超集。 @mah 你说的很多东西根本没有意义。以什么方式“不面向现有开发者”?就像Java不面向php开发人员一样? “面向那些可能不想成为开发人员的人”?是的,因为所有那些非开发人员都在使用面向协议的编程和泛型。 “实现好的设计的一种方式” 看看 SO,你会发现没有任何编程语言可以“实现好的设计”。【参考方案9】:var value : Int = 1
func theOldElegantWay() -> Int
return value++
func theNewFashionWay() -> Int
let temp = value
value += 1
return temp
这绝对是一个缺点,对吧?
【讨论】:
您的意思是优雅,就像“您必须记住 C 编程语言的所有细微之处,否则第一次调用返回 1 或 2 时不会立即明显”?我认为我们都可以节省几行额外的代码,以换取不用花几分钟摸索寻找由愚蠢错误引起的错误...【参考方案10】:由于您在 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
【讨论】:
【参考方案11】:在没有分号的语言中,它可能是模棱两可的。是前缀还是后缀运算符?
考虑:
var x = y
++x
人类读取++x
,但解析器可以将其读取为y++
。
【讨论】:
【参考方案12】:在 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 关于为什么要删除此运算符的推理(在之前的答案中提到)不仅是错误的推理,而且我认为这是一个谎言,真正的原因是他们无法让编译器处理它。在以前的版本中给他们带来了麻烦,所以他们放弃了。
“太复杂而无法理解运算符,因此被删除”的逻辑显然是一个谎言,因为 Swift 包含没有被删除的更复杂且更不实用的运算符。此外,绝大多数编程语言都有它。
javascript、C、C#、Java、C++ 等等。程序员乐于使用它。
无论谁太难理解这个运算符,他们并且只有他们应该使用 += (或者如果 += 也太复杂,也许 s = s + 1 )。
Swift 背后的策略很简单:Apple 认为程序员是愚蠢的,因此应该受到相应的对待。
事实上,2014 年 9 月推出的 Swift 到现在应该在其他地方。其他语言的发展速度要快得多。
我可以列出该语言中的许多主要错误,从严重的错误:例如按值而不是按引用粘贴的数组,到令人讨厌的错误:可变参数函数不能接受数组,这是其背后的全部思想。 我不认为 Apple 的员工甚至被允许查看其他语言,例如 Java,所以他们甚至不知道 Apple 落后了很多年。苹果本可以采用 Java 作为一种语言,但如今,挑战不是技术,而是自我。 如果他们会打开 IntelliJ 来编写一些 Java,那么他们肯定会关闭他们的业务,因为他们明白在这一点上,他们无法也永远不会赶上。
【讨论】:
以上是关于“++”和“--”运算符已被弃用 Xcode 7.3的主要内容,如果未能解决你的问题,请参考以下文章
kubectl (node:7) [MONGODB DRIVER] 警告:当前的服务器发现和监控引擎已被弃用,将在未来版本中删除
我是否需要更改我的Apps脚本代码,因为Google+登录功能已被弃用?