我正在查看Xcode 7.3注释,并且注意到了这个问题。
++和-运算符已被弃用
有人可以解释为什么不推荐使用它吗?我说对了,现在在新版本的Xcode中,您将使用它代替++
它x += 1
;
例:
for var index = 0; index < 3; index += 1 {
print("index is \(index)")
}
++
and --
运算符
我正在查看Xcode 7.3注释,并且注意到了这个问题。
++和-运算符已被弃用
有人可以解释为什么不推荐使用它吗?我说对了,现在在新版本的Xcode中,您将使用它代替++
它x += 1
;
例:
for var index = 0; index < 3; index += 1 {
print("index is \(index)")
}
++
and --
运算符
Answers:
Swift的创建者Chris Lattner 在这里提供了完整的解释。我将总结几点:
x += 1
for i = 0; i < n; i++ { ... }
,Swift有更好的选择,例如for i in 0..<n { ... }
(C样式的for循环也将淘汰)x - ++x
or 的值是foo(++x, x++)
多少?对于那些感兴趣的人(并避免链接腐烂),Lattner用他自己的话讲的理由是:
这些运算符增加了学习Swift作为第一门编程语言的负担-或在其他情况下您还不了解其他语言的运算符。
它们的表达优势极小-x ++比x + = 1短很多。
Swift已经偏离C,因为=,+ =和其他类似赋值的操作返回Void(出于多种原因)。这些运算符与该模型不一致。
Swift具有强大的功能,消除了您在其他语言中以C风格使用++ i进行循环的许多常见原因,因此在编写良好的Swift代码中相对很少使用这些原因。这些功能包括for-in循环,范围,枚举,映射等。
实际使用这些运算符的结果值的代码通常会使代码的读取器/维护者感到困惑和微妙。他们鼓励使用“过于棘手”的代码,这些代码可能很可爱,但很难理解。
尽管Swift具有明确定义的求值顺序,但是依赖于它的任何代码(如foo(++ a,a ++))也将是不可取的,即使它定义得很好。
这些运算符适用于相对较少的类型:整数和浮点标量,以及类似迭代器的概念。它们不适用于复数,矩阵等。
最后,这些没有通过“如果我们还没有这些,我们可以将它们添加到Swift 3吗?”的度量标准。
++
在C风格的语言中不存在它们,那么没有人会想到Swift 3.0的设计,并认为++
运算符将是对它的很好补充。
我意识到,尽管如此,此评论仍无法解决问题,可能有人会在寻找一种解决方案,以使这些操作员保持工作状态,这种解决方案可以在底部找到。😇
我个人更喜欢++
和--
运营商。我不同意它们棘手或难以管理的观点。一旦开发人员了解了这些运算符的功能(并且我们正在谈论非常简单的内容),则代码应该非常清楚。
在解释为什么不推荐使用运算符时,提到了它们的主要用途是C风格的for循环。我对其他人一无所知,但我个人根本不使用C风格的循环,在还有其他地方或情况下,++
或--
运算符很有用。
我还要提及的是,它varName++
返回一个值,因此可以在return
while中使用它,而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
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)
}
希望这可以帮助!
+=
一直在那里。
++i
和--i
?
克里斯·拉特纳(Chris Lattner)与++和-进行斗争。他写道:“实际上使用这些运算符的结果值的代码通常会使代码的读取器/维护者感到困惑和微妙。他们鼓励使用“过于棘手”的代码,这些代码可能很可爱,但很难理解……。尽管Swift的评估顺序已明确定义,但是依赖于该代码的任何代码(例如foo(++ a,a ++))都将是不受欢迎的定义明确...这些指标无法通过“如果我们还没有这些,我们可以将它们添加到Swift 3吗?”
苹果公司希望保持一种简洁,清晰,不混乱和直截了当的语言。因此,他们弃用了++和-关键字。
...for i in 0.stride(to: 10, by: 2)...
还是...for i in (1...10).reverse()...
干净的东西?
在Fix-it feature
Xcode中的提供了明确的答案。
更换++ increment operator
用老式的value += 1
(短手操作),并-- decrement operator
用value -= 1
对于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
,等。
您可以将这些扩展名粘贴到根目录中的单个文件中,并将在其中的所有其他文件中使用它们。
我注意到,几乎是在我发布该评论后,我在这里对我的回答进行了几次否决。我将其视为哲学上的分歧,而不是批评我的代码如何工作。如果您在操场上签出,它会完美地工作。
我之所以发布此答案,是因为我不同意使计算机编程语言彼此不必要地有所不同。
语言之间有很多相似之处,这使人们更容易学习和从一种语言切换到另一种语言。
开发人员通常使用多种编程语言,而不仅仅是一种。当没有约定,也没有跨语言的通用标准化时,从一种语言切换到另一种语言确实很麻烦。
我认为,语言之间的语法差异应仅在必要时,但不应超过此。
这是到目前为止发布的一些代码的通用版本。我会表达与其他人相同的担忧:最好的做法是不要在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
了每个功能,以使有关未使用返回值的警告保持沉默。否则,正是我想要的。
从文档:
Swift的增减运算符是在Swift的早期开发中添加的,是从C继承下来的。这些添加时没有过多考虑,并且从那时起就没有考虑太多。本文档对它们进行了全新的介绍,并最终建议我们将它们完全删除,因为它们会造成混淆并且不承担重量。
var value : Int = 1
func theOldElegantWay() -> Int{
return value++
}
func theNewFashionWay() -> Int{
let temp = value
value += 1
return temp
}
这绝对是一个缺点,对吗?
由于您从未真正在Swift中使用过指针,因此我认为删除++
and --
运算符是很有意义的。但是,如果您不能没有,可以将以下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
}
在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 ++等。程序员乐于使用它。谁很难理解这个运算符,
Swift背后的策略很简单:Apple认为程序员很笨,因此应该相应地对待它。
事实是,2014年9月推出的Swift到现在应该在其他地方了。其他语言的成长速度更快。
我可以列举该语言中的许多主要错误,从严重的错误开始,例如按值粘贴而不是按引用粘贴的数组,再到令人讨厌的错误:可变参数函数不能接受数组,这是其背后的全部思想。我认为苹果的员工甚至不被允许使用其他语言(例如Java),因此他们甚至都不知道苹果落后了几年。苹果本可以采用Java作为语言,但如今,挑战不是技术,而是自我。如果他们本来可以打开IntelliJ来编写一些Java,那么他们肯定会关闭他们的业务了解,因为这时他们永远也不会追上来。