it-roy-ru.com

Операторы "++" и "-" устарели в Xcode 7.3

Я смотрю на заметки Xcode 7.3 и замечаю эту проблему.

Операторы ++ и - устарели

Может ли кто-нибудь объяснить, почему это устарело? И я прав, что в новой версии XCode теперь вы собираетесь использовать вместо ++ этот x += 1;

Пример:

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

Screenshot for warning

135
Oleg Gordiichuk

A полное объяснение здесь от Криса Латтнера, создателя Swift. Я подведу итоги:

  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. Крису Латтнеру это не нравится.

Для тех, кто заинтересован (и чтобы избежать гниения ссылок), причины Латтнера, по его собственным словам:

  1. Эти операторы увеличивают бремя изучения Swift в качестве первого языка программирования - или любого другого случая, когда вы еще не знаете этих операторов из другого языка.

  2. Их выразительное преимущество минимально - х ++ не намного короче х + = 1.

  3. Swift уже отклоняется от C в том смысле, что =, + = и другие операции, подобные назначению, возвращают Void (по ряду причин). Эти операторы несовместимы с этой моделью.

  4. Swift обладает мощными функциями, которые устраняют многие из распространенных причин, по которым вы используете ++ i в цикле for в стиле C на других языках, поэтому они относительно редко используются в хорошо написанном Swift коде. Эти функции включают цикл for-in, диапазоны, перечисление, отображение и т.д.

  5. Код, который фактически использует значение результата этих операторов, часто вводит в заблуждение и тонок для читателя/сопровождающего кода. Они поощряют "чрезмерно хитрый" код, который может быть симпатичным, но трудным для понимания.

  6. Хотя Swift имеет четко определенный порядок вычисления, любой код, который зависит от него (например, foo (++ a, a ++)), будет нежелательным, даже если он будет четко определен.

  7. Эти операторы применимы к относительно небольшому числу типов: целочисленные скаляры и скаляры с плавающей точкой, а также итератороподобные концепции. Они не применяются к комплексным числам, матрицам и т.д.

Наконец, они не соответствуют метрике "если бы у нас их еще не было, мы бы добавили их в Swift 3?"

202
Code Different

Я понимаю, что этот комментарий не отвечает на вопрос, тем не менее, могут быть люди, которые ищут решение, как сохранить работу этих операторов, и такое решение можно найти внизу. ????

Я лично предпочитаю операторы ++ и --. Я не могу согласиться с мнением, что они сложны или сложны в управлении. Как только разработчик поймет, что делают эти операторы (а мы говорим о довольно простых вещах), код должен стать очень понятным.

В объяснении, почему операторы были объявлены устаревшими, упоминается, что их основное использование было в C-стиле для циклов. Я не знаю о других, но лично я вообще не использую циклы в стиле 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 удалила ++ и упростила его с помощью другого старого традиционного способа.

Вместо ++ вам нужно написать +=.

Пример:

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

Крис Латтнер пошел на войну с ++ и -. Он пишет: "Код, который на самом деле использует значение результата этих операторов, часто сбивает с толку и тонок для читателя/сопровождающего кода. Они поощряют "чрезмерно хитрый" код, который может быть симпатичным, но трудным для понимания…. Хотя Swift имеет четко определенный порядок вычисления, любой код, который зависит от него (например, foo (++ a, a ++)) было бы нежелательно, даже если бы он был четко определен… они не соответствуют метрике "если бы у нас их еще не было, мы бы добавили их к Swift 3?" "

Apple хотела, чтобы Swift был чистым, понятным, понятным и понятным языком. И поэтому они устарели ++ и - ключевое слово.

8
Jay Mehta

Screenshot for warning

Fix-it feature из Xcode дает четкий ответ на это.

Solution to warning

Замените ++ increment operator старомодным value += 1 (оператор сокращения) и -- decrement operator с value -= 1

6
Jayprakash Dubey

Из документов :

Операторы увеличения/уменьшения в Swift были добавлены очень рано при разработке Swift, как перенос из C. Они были добавлены без особого рассмотрения, и с тех пор о них почти не думали. Этот документ дает новый взгляд на них и в конечном итоге рекомендует просто полностью удалить их, поскольку они сбивают с толку и не несут своего веса.

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

Он работает аналогичным образом для других типов, таких как UIInt, Int8, Float, Double и т.д.

Вы можете вставить эти расширения в один файл в корневом каталоге, и они будут доступны для использования во всех других ваших файлах.

Я заметил пару отрицательных голосов за мой ответ, почти сразу после того, как я его опубликовал. Который я принимаю как философское несогласие, а не критику того, как работает мой код. Это отлично работает, если вы проверите это на детской площадке.

Причина, по которой я опубликовал этот ответ, заключается в том, что я не согласен с тем, что языки программирования неоправданно отличаются друг от друга.

Наличие большого сходства между языками делает их более легкими для изучения людьми и переключения с одного языка на другой.

Разработчики обычно используют несколько языков программирования, а не только один. А переход с одного языка на другой - это настоящая проблема, когда нет соглашений и нет общей стандартизации между языками.

Я считаю, что синтаксические различия между языками должны быть настолько большими, насколько это необходимо, и не более того.

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
}

Это также можно записать как расширение типа Numeric.

0
Doghound