web-dev-qa-db-ja.com

"++"および " - "演算子はXcode 7.3で非推奨になりました

Xcode 7.3のノートを見ていますが、この問題に気付きました。

++および - 演算子は推奨されなくなりました

非推奨となった理由を説明できる人もいますか。そして、Xcodeの新バージョンでは、++ this x += 1の代わりに使うことになるでしょう。

例:

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

Screenshot for warning

135
Oleg Gordiichuk

A ここでの完全な説明 Swiftの作成者であるChris Lattnerによる。ポイントを要約します。

  1. それはあなたがSwiftを学んでいる間あなたが学ばなければならないもう一つの機能です
  2. x += 1ほど短くはありません
  3. SwiftはCではありませんCのプログラマーを喜ばせるためだけに持ち越してはいけません
  4. その主な用途はCスタイルのループです:for i = 0; i < n; i++ { ... }、Swiftにはfor i in 0..<n { ... }のようなより良い選択肢があります(ループのCスタイルは 同様に出て行く
  5. たとえば、x - ++xまたはfoo(++x, x++)の値は何でしょうか。
  6. Chris Lattnerはそれが好きではありません。

興味がある人のために(そしてリンクの腐敗を避けるために)、彼自身の言葉でのラットナーの理由は、

  1. これらの演算子は、Swiftを最初のプログラミング言語として学習する負担を増大させます。あるいは、これらの演算子を別の言語からまだ知っていない他の場合も同様です。

  2. それらの表現上の利点はごくわずかです - x ++はx + = 1よりもずっと短くはありません。

  3. Swiftは既にCとは異なり、=、+ =、その他の代入風の操作でVoidが返されます(いくつかの理由で)。これらの演算子はそのモデルと矛盾しています。

  4. Swiftには、他の言語でC++スタイルでループするために++ iを使用する一般的な理由の多くを排除する強力な機能があるため、これらはよく書かれたSwiftコードでは比較的まれにしか使用されません。これらの機能にはfor-inループ、範囲、列挙、マップなどがあります。

  5. これらの演算子の結果値を実際に使用するコードは、コードの読者/管理者にとっては紛らわしくて微妙です。彼らはかわいいかもしれないが理解するのが難しいかもしれない「過度にトリッキーな」コードを勧めます。

  6. Swiftには明確に定義された評価の順序がありますが、それに依存するコード(foo(++ a、a ++)のような)は、それが明確に定義されていても望ましくありません。

  7. これらの演算子は、比較的少数の型、つまり整数と浮動小数点のスカラー、および反復子のような概念に適用できます。複素数、行列などには適用されません。

最後に、これらは「まだ持っていない場合、Swift 3に追加しますか?」という測定基準に失敗します。

202
Code Different

このコメントは質問に答えないにもかかわらず、これらの演算子を機能させ続ける方法を探している人たちがいるかもしれませんし、そのような解決策は一番下にあります。 ????

私は個人的には++--演算子を好みます。私は彼らが扱いにくいか、または管理するのが難しいという意見に同意できません。開発者がこれらの演算子の動作を理解したら(そして私たちはかなり単純なことについて話しています)、コードは非常に明確になるはずです。

なぜ演算子が非推奨になったのかの説明では、主な用途は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
}
35
0101

Appleは++を削除し、もう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)
}

あなたは書くことができます:

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

お役に立てれば!

22
Sohil R. Memon

Chris Lattnerは++と - と戦っています。彼は次のように書いています。「実際にこれらの演算子の結果の値を使用するコードは、コードの読者/管理者にとっては紛らわしくて微妙です。彼らはかわいいが理解しにくいかもしれない「過度にトリッキーな」コードを奨励します…。Swiftが明確に評価の順序を持​​っています、それに依存するどんなコード(foo(++ a、a ++)のような)も明確に定義されていました…これらは「まだ持っていなければSwift 3に追加しますか?」という測定基準に合格しません。

Appleは、Swiftを清潔で、明快で、混乱しない、直接的なポイント言語にしたいと考えていました。そして彼らは++と - keywordを廃止しました。

8
Jay Mehta

Screenshot for warning

XcodeのFix-it featureはこれに対する明確な答えを与えます。

Solution to warning

++ increment operatorを昔のvalue += 1(省略形の演算子)に、-- decrement operatorvalue -= 1にそれぞれ置き換えます。

6

のドキュメントから

Swiftのインクリメント/デクリメント演算子は、Cからのキャリーオーバーとして、Swiftの開発のごく初期に追加されました。これらは、あまり考慮されずに追加され、それ以来あまり考えられませんでした。このドキュメントはそれらを新鮮に見せています、そして、それらが混乱していて、彼らの体重を運んでいないので、結局私たちがそれらを完全に取り除くことを勧めます。

4
Dániel Nagy

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などの他の型でも同じように機能します。

これらの拡張子はあなたのルートディレクトリの単一のファイルに貼り付けることができ、そこにあるあなたの他のすべてのファイルの中で使用できるようになります。

私はそれを投稿した直後に、ここで私の答えに2、3の下落票に気づいた。私のコードがどのように機能するかについての批判ではなく、これは哲学的な意見の相違として捉えています。あなたが遊び場でそれをチェックアウトすれば、それは完璧に機能します。

私がこの答えを投稿したのは、私がコンピュータープログラミング言語を不必要に互いに異なるものにすることに反対しているからです。

言語間に多くの類似点があると、人々が学び、ある言語から別の言語に切り替えるのが容易になります。

開発者は通常、1つだけではなく複数のプログラミング言語を使用します。また、慣例がなく、言語間で共通の標準化がない場合、ある言語から別の言語に切り替えるのは本当に面倒です。

私は、言語間の構文の違いは必要な分だけであり、それ以上の違いはないはずだと思います。

3
Mike

これはこれまでに投稿されたコードのいくつかの一般的なバージョンです。私は他の人たちと同じ懸念を表明します: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
}

これは数値型の拡張としても書くことができます。

0
Doghound
var value : Int = 1

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

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

これは間違いなく欠点ですよね?

0
outcast