Подтвердить что ты не робот

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

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

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

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

Пример:

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

Снимок экрана для предупреждения

4b9b3361

Ответ 1

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

  • Это еще одна функция, которую вы должны изучить, изучая Swift
  • Не намного меньше x += 1
  • Swift не C. Не следует переносить их только для того, чтобы угодить программистам C.
  • Его основное использование - в цикле цикла C: for i = 0; i < n; i++ { ... }, у которого Swift имеет лучшие альтернативы, например for i in 0..<n { ... } (C-стиль для цикла выходят также)
  • Может быть сложно читать и поддерживать, например, какое значение x - ++x или foo(++x, x++)?
  • Крису Лэтттеру это не нравится.

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

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

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

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

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

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

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

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

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

Ответ 2

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

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

В объяснении, почему операторы были устаревшими, упоминается, что их основное использование было в стиле 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
}

Ответ 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)
}

Надеюсь, это поможет!

Ответ 4

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

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

Ответ 5

Снимок экрана для предупреждения

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

Решение для предупреждения

Замените ++ increment operator старомодным value += 1 (short-hand operator) и -- decrement operator на value -= 1

Ответ 6

Из docs:

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

Ответ 7

Для 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 и т.д.

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

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

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

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

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

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

Ответ 8

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

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.

Ответ 9

var value : Int = 1

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

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

Это определенно недостаток, верно?

Ответ 10

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

// This appears to work, so you don't need a temp var,
// you do need to pass something in or have it be a 
// method on the struct or class.
// I probably wouldn't actually write a function
// just to increment a given value.  
// I'd just increment it where I needed too.
// Otherwise, you copy a value and return it.

func otherNewIncrement(newValue : Int) -> Int {
    return newValue + 1
}

Ответ 11

i += 1 возвращает Void, что является наиболее важной точкой. Таким образом, ++i и i++ возвращают Void. Они будут иметь то же значение. В это время вы поймете, что удаление лучше, как это делает Python.

Ответ 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, С#, Java, C++ и многие другие. Программисты счастливо используют его. Кому это сложно понять для этого оператора, они и только они должны делать + = (или, может быть, s = s + 1, если + = тоже слишком сложно).

Стратегия, лежащая в основе Swift, проста: Apple считает, что программист немой и поэтому следует относиться соответствующим образом.

Правда в том, что Swift, запущенный в сентябре 2014 года, должен был быть где-то еще. Другие языки росли гораздо быстрее.

Я могу перечислить многие серьезные ошибки на языке, от серьезных: массивы, вставленные по значению, а не по ссылке, в раздражающие: функции вариационных параметров не могут принять массив, который является всей идеей. Я не думаю, что сотрудникам Apple даже разрешено смотреть на другие языки, такие как Java, поэтому они даже не знают, что Apple на несколько лет отстает. Apple могла бы принять Java как язык, но в наши дни проблема не в технологии, а в эго. Если бы они открыли IntelliJ для написания Java, они наверняка закроют свое понимание бизнеса, что на данный момент они не могут и не смогут догнать когда-либо.