Что именно ++ означает в Swift?

Я изучаю Swift с книгой, предназначенной для людей с небольшим опытом. Меня беспокоит синтаксис ++. Следующее взято из книги:

var counter = 0
let incrementCounter = {
  counter++
}
incrementCounter()
incrementCounter()
incrementCounter()
incrementCounter()
incrementCounter()

в книге сказано, что счетчик 5.

но я набрал эти коды на игровой площадке Xcode. Это 4!

я сбит с толку.

5 ответов

Решение

Операторы после увеличения и после уменьшения увеличивают (или уменьшают) значение своего операнда на 1, но значение выражения является исходным значением операнда перед операцией увеличения (или уменьшения)

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

детская площадка

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

++ и - перед идентификатором прибавляют / вычитают единицу, а затем возвращают его значение.
++ и - после идентификатора возвращают его значение, а затем прибавляют / вычитают 1.

Они были удалены в Swift 3.0, но вы можете добавить их обратно:

prefix operator --
prefix operator ++
postfix operator --
postfix operator ++

prefix func ++(_ a : inout Int) -> Int {
    a += 1
    return a
}
prefix func --(_ a : inout Int) -> Int {
    a -= 1
    return a
}
postfix func ++(_ a: inout Int) -> Int {
    defer { a += 1 }
    return a
}
postfix func --(_ a: inout Int) -> Int {
    defer { a -= 1 }
    return a
}

var a = 11
print(a++) // 11
print(a)   // 12

var b = 5
print(--b) // 4
print(b) // 4

Значение counter после ваших пяти звонков incrementCounter закрытие будет 5, но возврат каждого звонка incrementCounter будет, казалось бы, "отставать" на шаг назад. Как пишет Sulthan в своем ответе, это связано с x++ будучи оператором постинкремента: результат выражения будет возвращен до инкремента

var x = 0
print(x++) // 0
print(x)   // 1

Кроме того, как я написал в моем комментарии выше, вы не должны использовать ++ а также -- операторы, поскольку они будут устаревшими в Swift 2.2 и удалены в Swift 3. Тем не менее, если вам интересны подробности об операторе пост-инкремента post, вы можете найти хорошие ответы здесь на SO, помеченной для других языков, но охватывающей ту же тему, например


Стоит упомянуть, однако, пункт, который имеет отношение к Swift > 2.1, и который на самом деле не относится к ++ Оператор конкретно.

Когда вы начинаете закрытие incrementCounter как

var someOne : Int = 0
let incrementCounter = {
    someInt
}

Закрытие подразумевается как тип () -> Int: замыкание, принимающее нулевые аргументы, но с единственным возвратом типа Int,

let incrementCounter: () -> Int = {
    return someInt
}

Следовательно, то, что вы, по-видимому, "видите" на своей игровой площадке, - это неиспользованное (неназначенное) возвращаемое значение вызова incrementCounter закрытие; т. е. результат выражения incrementCounter(),

введите описание изображения здесь

В то время как стоимость counter никогда не печатается в правильном блоке вашей игровой площадки (если вы не напишите строку, где результат этой строки: s выражение counter).

x++ operator - это оператор, который используется на нескольких языках - C, C++, Java (см. ответ на C для того же вопроса)

Это называется постинкремент. Увеличивает заданную переменную на единицу, но после вычисления текущего выражения. Например:

var x = 1
var y = 2 + x++
// the value of x is now 2 (has been incremented)
// the value of y is now 3 (2 + 1, x has been evaluated before increment)

Это отличается от ++x (предварительное увеличение) оператор:

var x = 1
var y = 2 + ++x
// the value of x is now 2 (has been incremented)
// the value of y is now 4 (2 + 4, x has been evaluated after increment)

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

Всегда лучше просто написать x += 1 вместо сложных выражений с побочными эффектами.

Несмотря на то, что ответов много, и все они ясны, я добавил этот фрагмент, чтобы показать вам, как заменить код новым синтаксисом, где ++ и или - устарели. сначала ваш собственный код

var counter = 0
let incrementCounter = {
    counter++
}
let i0 = incrementCounter() // 0
let i1 = incrementCounter() // 1
// .....

как переписать его в будущем синтаксисе Swift? давайте попробуем рекомендуемую замену...

var counter = 0
let ic = {
    counter += 1
}
let i0 = ic() // () aka Void !!!
let i1 = ic() // ()

но теперь результатом ic() является Void! Хм... ОК, следующая попытка может выглядеть

var counter = 0
let ic = {
    counter += 1
    return counter
}

но теперь код не компилируется с ошибкой: невозможно определить тип возвращаемого значения замыкания в текущем контексте:-), поэтому мы должны объявить его (в нашей исходной версии это было необязательно)

var counter = 0
let ic:()->Int = {
    counter += 1
    return counter
}
let i0 = ic() // 1
let i1 = ic() // 2
// .....

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

var counter = 0
let ic:()->Int = {
    let ret = counter
    counter += 1
    return ret
}
let i0 = ic() // 0
let i1 = ic() // 1
// .....

да, я хотел бы видеть мои знакомые унарные ++ и / или - будут также в будущих версиях Swift

То, что вы делаете, это постинкремент.

Сначала узнайте разницу между до и после приращения

  1. В Постинкрементном счетчике значения после инкремента содержится увеличенное значение (т. Е. 5), но если мы вернемся, то оно будет содержать старое значение (т. Е. 4).
  2. В режиме предварительного увеличения значение и возвращаемое значение увеличиваются.

Давайте посмотрим на ваш код сейчас,

counter++ делает копию, увеличивает счетчик и возвращает копию (старое значение).

поэтому, если вы напечатаете счетчик, он будет иметь увеличенное значение (т.е. 5), но, если вы вернете счетчик (т.е. вы делаете это с incrementCounter), он будет содержать старое значение (то есть 4).

из-за которого incrementCounter показывает только до 4.

ПРОВЕРИТЬ ВЫХОД введите описание изображения здесьРешение:

менять counter++ в ++counter

ПРОВЕРИТЬ ВЫХОД введите описание изображения здесь

Другие вопросы по тегам