Зачем мне нужны символы подчеркивания? - программирование

Зачем мне нужны символы подчеркивания?

Здесь в нем говорится: "Примечание: _ означает" Я не забочусь об этом значении", но исходящий из JavaScript, я не понимаю, что это значит.

Единственный способ, которым я могу получить эти функции для печати, - это использовать подчеркивания перед параметрами:

func divmod(_ a: Int, _ b:Int) -> (Int, Int) {
    return (a / b, a % b)
}

print(divmod(7, 3))
print(divmod(5, 2))
print(divmod(12,4))

Без подчеркивания я должен написать это так, чтобы избежать ошибок:

func divmod(a: Int, b:Int) -> (Int, Int) {
    return (a / b, a % b)
}

print(divmod(a: 7, b: 3))
print(divmod(a: 5, b: 2))
print(divmod(a: 12,b: 4))

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

4b9b3361

Ответ 1

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


При объявлении новой функции подчеркивание указывает Swift, что параметр не должен иметь метки при вызове - это случай, который вы видите. Объявление более полной функции выглядит следующим образом:

func myFunc(label name: Int) // call it like myFunc(label: 3)

"label" - это метка аргумента и должна присутствовать при вызове функции. (И поскольку Swift 3, по умолчанию для всех аргументов требуются метки.) "Name" - это имя переменной для этого аргумента, который вы используете внутри функции. Более короткая форма выглядит следующим образом:

func myFunc(name: Int) // call it like myFunc(name: 3)

Это ярлык, который позволяет использовать одно и то же слово для ярлыка внешних аргументов и внутреннего имени параметра. Это эквивалентно func myFunc(name name: Int).

Если вы хотите, чтобы ваша функция вызывалась без ярлыков параметров, вы используете знак подчеркивания _, чтобы сделать ярлык ничем/проигнорированным. (В этом случае вам нужно указать внутреннее имя, если вы хотите использовать этот параметр.)

func myFunc(_ name: Int) // call it like myFunc(3)

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

_ = someFunction()

Или, как и в статье, к которой вы привязались, игнорировать один элемент возвращаемого кортежа:

let (x, _) = someFunctionThatReturnsXandY()

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

PHPhotoLibrary.performChanges( { /* some changes */ },
    completionHandler: { success, _ in // don't care about error
        if success { print("yay") }
    })

Аналогично, при объявлении функции, которая принимает протокол или переопределяет метод суперкласса, вы можете использовать _ для имен параметров для игнорирования параметров. Поскольку протокол/суперкласс также может определять, что параметр не имеет метки, вы можете даже получить два символа подчеркивания в строке.

class MyView: NSView {
    override func mouseDown(with _: NSEvent) {
        // don't care about event, do same thing for every mouse down
    }
    override func draw(_ _: NSRect) {
        // don't care about dirty rect, always redraw the whole view
    }
}

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

for _ in 1...20 { // or 0..<20
    // do something 20 times
}

Если вы связываете случаи набора кортежей в инструкции switch, подчеркивание может работать как подстановочный знак, как в этом примере (сокращенно от одного в языке Swift Programming):

switch somePoint { // somePoint is an (Int, Int) tuple
case (0, 0):
    print("(0, 0) is at the origin")
case (_, 0):
    print("(\(somePoint.0), 0) is on the x-axis")
case (0, _):
    print("(0, \(somePoint.1)) is on the y-axis")
default:
    print("(\(somePoint.0), \(somePoint.1)) isn't on an axis")
}

Ответ 2

Так как Swift 3, указание имен параметров на вызовы функций стало обязательным - даже для первого. Поэтому, поскольку это может вызвать огромную проблему для кода, написанного в swift 2, вы можете использовать знак подчеркивания в объявлении, чтобы не было необходимости писать имя параметра при вызове. Поэтому в этом случае он говорит "не заботятся о имени внешнего параметра". Если имя внешнего параметра - это то, что вы вызываете параметры вне функции (по вызову), а не внутри. Эти внешние имена параметров называются метками аргументов. http://ericasadun.com/2016/02/09/the-trouble-with-argument-labels-some-thoughts/... посмотреть, как параметру присваиваются два имени? ну, во-первых, это подчеркивание подчеркивания. Надеюсь, это поможет, и спросите, все еще запутано.

Ответ 3

func divmod(_ a: Int, _ b:Int) -> (Int, Int) {
    return (a / b, a % b)
}

func divmod(a: Int, b:Int) -> (Int, Int) {
    return (a / b, a % b)
}

_ является заполнителем для имени параметра. В вашем примере вы называете их по-разному, во второй функции вам нужно написать имя параметра a: 1.

Соглашение о назначении функции Swift - это funcName(param1:param2:), и для создания имени функции требуется _ в качестве заполнителя.

При имени имя

divmod(_:_:)

В то время как вторая

divmod(a:b:)