Что представитель подчеркивания в Swift References?

В справочном разделе Apple docs есть много примеров такого рода:

func runAction(_ action : SKAction!)

Objective-C 'эквивалент' этого:

- (void)runAction:(SKAction *) action

Мне кажется, что, вероятно, важно, чтобы (в ссылке Swift) пробел после подчеркивания и "действие" было написано курсивом.

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

- здесь страница, на которую я ссылаюсь в этой ссылке на использование подчеркивания: https://developer.apple.com/documentation/spritekit/sknode#//apple_ref/occ/instm/SKNode/runAction

Update

Swift 3 внесла некоторые изменения в то, как используются имена и имена параметров функции и метода, а также имена названий. Это имеет последствия для этого вопроса и его ответа. @Rickster делает удивительную работу, отвечая на другой вопрос о _underscores в функциях, которые очищают большую часть этого, здесь: Почему мне нужны символы подчеркивания в быстром?

Ответ 1

Оба ответа были правильными, но я хочу уточнить немного больше.

_ используется для изменять поведение имени внешнего параметра для методов.

В разделе в разделе "Локальные и внешние параметры имен методов" в документации говорится:

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

С другой стороны, функции по умолчанию не имеют внешних имен параметров.

Например, у нас есть этот метод foo(), определенный в классе Bar:

class Bar{
    func foo(s1: String, s2: String) -> String {
        return s1 + s2;
    }
}

Когда вы вызываете foo(), он называется как bar.foo("Hello", s2: "World").

Но вы можете переопределить это поведение, используя _ перед s2, где он был объявлен.

func foo(s1: String, _ s2: String) -> String{
    return s1 + s2;
}

Затем, когда вы вызываете foo, его можно просто вызвать как bar.foo("Hello", "World") без имени второго параметра.

Вернемся к вашему случаю, runAction - это метод, потому что он связан с типом SKNode, очевидно. Таким образом, добавление параметра _ до параметра action позволяет вызывать runAction без внешнего имени.

Обновление для Swift 2.0

Функция и метод теперь работают одинаково в терминах объявления локального и внешнего аргументов.

Теперь функции вызывается с использованием внешнего имени параметра по умолчанию, начиная со второго параметра. Это правило применяется только к чистому коду Swift.

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

Ответ 2

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

В этом конкретном случае это означает, что функция будет вызываться как runAction(argument) вместо runAction(action:argument)

В других контекстах он имеет другое сходное значение, например. в:

for _ in 0..<5 { ... }

Это означает, что мы просто хотим выполнить блок 5 раз, и нам не нужен индекс внутри блока.

В этом контексте:

let (result, _) = someFunctionThatReturnsATuple()

Это означает, что нам все равно, что второй элемент кортежа, только первый.

Ответ 3

Идентификатор перед объявлением параметра определяет имя внешнего параметра. Это имя, которое должно быть предоставлено вызывающим абонентом при вызове функции:

func someFunction(externalParameterName localParameterName: Int)

Swift предоставляет автоматическое внешнее имя для любого дефолтного параметра, который вы определяете, если вы не предоставляете внешнее имя самостоятельно. Использование подчеркивания для внешнего имени параметра отказывается от этого поведения:

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

Подробнее об этом поведении читайте в разделе "Внешние имена для параметров со значениями по умолчанию здесь.

Ответ 4

Так как Swift 3 все метки меток требуются по умолчанию.

Вы можете заставить среду IDE скрыть метку аргумента с помощью _.

func foo(a: String) {
}

func foo2(_ a: String) {
}

называется foo(a: "abc") и foo2("abc")

Примечание.. Это можно использовать только тогда, когда a является (внешним) символом аргумента и (внутренним) именем переменной одновременно. Он эквивалентен - func foo(a a: String) не принимает _.

Почему Apple использует его?

Вы можете видеть, что Apple использует его через API. Библиотеки Apple по-прежнему записываются в формате Objective-C (если нет, они имеют одинаковые имена функций, которые были разработаны для синтаксиса Objective-C)

Такие функции, как applicationWillResignActive(_ application: UIApplication), имеют избыточное имя параметра application, так как в нем есть имя приложения.

Ваш пример

func runAction(_ action: SKAction!) будет называться без _, как runAction(action:). Имя параметра action будет избыточным, поскольку в имени функции уже есть один. Это цель и почему она там.

Ответ 5

Я думаю, что это принуждает соглашение в Swift, что делает его ближе к objective-c, что лучше соответствует соглашениям cocoa. В objc вы не (внешне) назовите свой первый параметр. Вместо этого, по соглашению, вы обычно включаете внешнее имя в последней части имени метода следующим образом:

- (void)myFancyMethodWithFirstName:(NSString *)aFirstName lastName:(NSString *)aLastName;

[someInstance myFancyMethodWithFirstName:@"John" lastName:@"Doe"];

Чтобы сделать вызовы Swift api совместимыми с objc, вы захотите подавить имя внешнего параметра первого параметра.

func myFancyMethodWithFirstName(_ firstName:String, lastName:String);

someInstance.myFancyMethodWithFirstName("John", lastName:"Doe")

Ответ 6

На самом деле существует разница между реальным кодом, используемым для определения метода и объявления метода в документах Apple. Возьмем UIControl - addTarget: действие: forControlEvents: метод, например, настоящий код:  enter image description here

Но в документах это выглядит так (уведомление _ перед мишенью): enter image description here

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

Нет внешнего имени, если функция вызывается по умолчанию, если вы не указали свой собственный или не добавили # перед (без пробела) локальное имя параметра, например, так мы используем dispatch_after: enter image description here

И в документах это выглядит так (обратите внимание на три _): enter image description here

Согласование объявления функции является таким же, как я описал для метода.

Ответ 7

Просто визуально.

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

Как вы можете видеть, _ просто опустить имя локального параметра или нет.