Xcode 7.3のノートを見ていると、この問題に気づきました。
++および-演算子は廃止されました
誰かがなぜそれが非推奨であるかを説明できますか?Xcodeの新しいバージョンでは、++これの代わりに使用することになりますx += 1。
例:
for var index = 0; index < 3; index += 1 {
print("index is \(index)")
}
++さらに--演算子や演算子を使用する必要がなくなります
Xcode 7.3のノートを見ていると、この問題に気づきました。
++および-演算子は廃止されました
誰かがなぜそれが非推奨であるかを説明できますか?Xcodeの新しいバージョンでは、++これの代わりに使用することになりますx += 1。
例:
for var index = 0; index < 3; index += 1 {
print("index is \(index)")
}
++さらに--演算子や演算子を使用する必要がなくなります
回答:
Swiftの作成者であるChris Lattnerによる、ここでの完全な説明。ポイントを要約します。
x += 1for i = 0; i < n; i++ { ... }であり、Swiftにはfor i in 0..<n { ... }(Cスタイルのforループも出ていく)など、より優れた代替案があります。x - ++xまたはの値は何foo(++x, x++)ですか?興味のある人(リンクの腐敗を避けるため)にとって、ラトナーの言葉には次のようなものがあります。
これらの演算子は、Swiftを最初のプログラミング言語として学習するための負担を増やします-または、別の言語からこれらの演算子をまだ知らないその他の場合。
それらの表現上の利点は最小限です-x ++はx + = 1よりもはるかに短くありません。
SwiftはすでにCから外れていますが、=、+ =、および他の代入のような演算は(いくつかの理由で)Voidを返します。これらの演算子はそのモデルと一致していません。
Swiftには強力な機能があり、他の言語のCスタイルのforループで++ iを使用する一般的な理由の多くを排除するため、これらはよく書かれたSwiftコードで比較的まれに使用されます。これらの機能には、for-inループ、範囲、列挙、マップなどが含まれます。
これらの演算子の結果値を実際に使用するコードは、多くの場合、コードのリーダー/メンテナーにとってわかりにくく、微妙です。彼らは、可愛くても理解しにくい「過度にトリッキー」なコードを奨励しています。
Swiftの評価順序は明確に定義されていますが、それに依存するコード(foo(++ a、a ++)など)は、明確に定義されていても望ましくありません。
これらの演算子は、比較的少数のタイプ(整数および浮動小数点スカラー、およびイテレーターのような概念)に適用できます。複素数、行列などには適用されません。
最後に、これらは「まだ持っていない場合、Swift 3に追加しますか?」というメトリックに失敗します。
++がCスタイルの言語に存在しなかった場合、正しい考えの誰もがSwift 3.0の設計を見て、++演算子がそれに素晴らしい追加になるとは考えません。
このコメントは質問に答えるものではありませんが、これらのオペレーターを稼働させ続ける方法を探している人がいるかもしれません。そのような解決策は下部にあります。😇
個人的には++と--演算子を好みます。それらが扱いにくいか、管理が難しいという意見には同意できません。開発者がこれらの演算子が何をするかを理解したら(そして、かなり単純なことについて話しています)、コードは非常に明確になるはずです。
演算子が非推奨になった理由の説明では、その主な用途は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
Appleはを削除++し、別の古い伝統的な方法でそれをはるかに簡単にしました。
の代わりに++、あなたが書く必要があります+=。
例:
var x = 1
//Increment
x += 1 //Means x = x + 1
同様に、デクリメント演算子の--場合、次のように記述する必要があります-=
例:
var x = 1
//Decrement
x -= 1 //Means x = x - 1
for 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に追加しますか?」というメトリックに失敗しました。
Appleは、すっきりとした、明確で、混乱のない、わかりやすい直言を迅速に維持したいと考えていました。そのため、彼らは++および-キーワードを廃止しました。
...for i in 0.stride(to: 10, by: 2)...または...for i in (1...10).reverse()...きれいですか?
Fix-it featureXcodeののは、これに対する明確な答えを与えます。
置き換え++ 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、など
これらの拡張機能をルートディレクトリの1つのファイルに貼り付けると、そこにある他のすべてのファイル内で使用できるようになります。
投稿してすぐに、ここで私の回答に対するいくつかの反対票に気づきました。私のコードがどのように機能するかについての批判ではなく、私はそれを哲学的な不一致とみなします。遊び場でチェックアウトすれば、完全に機能します。
私がこの回答を投稿したのは、コンピュータプログラミング言語を不必要に異なるものにすることには同意しないためです。
言語間で多くの類似点があると、人々が学習しやすく、ある言語から別の言語に切り替えることが容易になります。
開発者は通常、1つではなく複数のプログラミング言語を使用します。また、慣習や言語間での共通の標準化がない場合、ある言語から別の言語に切り替えるのは本当に面倒です。
言語間の構文の違いは、必要な分だけで、これ以上はないと思います。
これは、これまでに投稿されたコードの一部の一般的なバージョンです。他の人と同じ懸念を表明します。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
}
これは、数値型の拡張として書くこともできます。
@discardableResultこれらの各関数に追加して、戻り値が未使用であるという警告を抑制しました。そうでなければ、まさに私が探していたもの。
ドキュメントから:
Swiftのインクリメント/デクリメント演算子は、Cからの持ち越しとして、Swiftの開発の非常に早い段階で追加されました。これらはあまり考慮されずに追加され、それ以来あまり考えられていません。このドキュメントでは、それらの見た目が新しくなり、混乱を招き、重要度が低下するため、最終的には完全に削除することをお勧めします。
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++2つのことを行います。tの値をsに割り当て、tをインクリメントします。++が前にある場合、それは逆の順序で行われる同じ2つの操作です。私の意見では、この演算子を削除する理由についてのAppleの推論(以前の回答で述べた)は誤った推論であるだけでなく、それは嘘であると私は信じています。以前のバージョンでは問題が発生したため、あきらめました。「演算子を理解するには複雑すぎるため、削除されました」というロジックは明らかに嘘です。Swiftには、削除されなかったはるかに複雑であまり有用ではない演算子が含まれているためです。また、プログラミング言語の大部分はそれを持っています。JavaScript、C、C#、Java、C ++などなど。プログラマーは喜んでそれを使います。この演算子を理解するのが難しすぎる場合は、
Swiftの背後にある戦略は単純です。Appleはプログラマーが愚かであり、したがって適切に扱う必要があると信じています。
真実は、2014年9月に発売されたSwiftが今までどこか別の場所にあるはずだったということです。他の言語ははるかに速く成長しました。
参照によるものではなく値によって貼り付けられた配列などの深刻なものから、厄介なものまで、言語の多くの主要な間違いをリストできます。可変引数パラメーター関数は、その背後にある全体的な考えである配列を受け入れることができません。Appleの従業員がJavaのような他の言語を見ることさえ許されていないと私は思うので、彼らはAppleが光年遅れていることさえ知らない。Appleは言語としてJavaを採用できたかもしれませんが、最近の課題はテクノロジーではなく、エゴです。彼らがIntelliJを開いてJavaを書くとしたら、彼らはこの時点では追いつくことができず、追いつくことができないというビジネス上の理解を確実に閉じます。