2016-09-21 18 views
57

mówi: "Uwaga: _ oznacza" Nie dbam o tę wartość "", ale pochodząc z JavaScript, nie rozumiem, co to oznacza.Dlaczego potrzebuję podkreśleń w szybkim tempie?

Jedynym sposobem mogę dostać te funkcje do druku był za pomocą podkreślenia przed parametrach:

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

bez podkreślenia muszę napisać to tak, aby uniknąć wszelkich błędów:

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

Nie rozumiem tego użycia podkreślenia. Kiedy, jak i dlaczego używam tych podkreśleń?

Odpowiedz

143

Istnieje kilka niuansów do różnych przypadków użycia, ale ogólnie podkreślenia oznacza „ignoruj ​​tego”.


Deklarując nową funkcję, podkreślenia Swift mówi, że parametr nie powinien mieć etykietę po nazwie - to przypadek widzisz. Pełniejsza deklaracja funkcji wygląda następująco:

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

"etykieta" jest etykietą argumentu i musi być obecna podczas wywoływania funkcji. (A od Swift 3 etykiety są wymagane domyślnie dla wszystkich argumentów.) "Name" to nazwa zmiennej dla tego argumentu, którego używasz wewnątrz funkcji. Krótsza forma wygląda następująco:

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

Jest to skrót, który pozwala używać tego samego słowa na etykiecie argumentów zarówno zewnętrznych i wewnętrznych nazwy parametru. Jest to odpowiednik func myFunc(name name: Int).

Jeśli chcesz, aby funkcja mogła być wywoływana bez etykiet parametrów, użyjesz podkreślenia _, aby etykieta była pusta/ignorowana. (W takim przypadku musisz podać wewnętrzną nazwę, jeśli chcesz móc korzystać z parametru.)

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

W instrukcji przypisania, podkreślenia oznacza "nie przypisywać do niczego". Możesz użyć tego, jeśli chcesz wywołać funkcję, która zwraca wynik, ale nie przejmuj się zwróconą wartością.

_ = someFunction() 

Albo, jak w artykule jesteś związana, aby ignorować jeden element zwrócony krotki:

let (x, _) = someFunctionThatReturnsXandY() 

Kiedy piszesz zamknięcie, które implementuje jakiś określony typ funkcji, można użyj znaku podkreślenia, aby zignorować określone parametry.

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

Podobnie, gdy deklarując funkcję, która przyjmuje protokół lub nadpisuje metodę klasy nadrzędnej, można użyć _ parametru nazwy zignorować parametrów. Ponieważ protokół/nadklasa może również definiować, że parametr nie ma etykiety, można nawet skończyć z dwoma podkreśleniami w wierszu.

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

Nieco podobne do ostatnich dwóch stylach: przy użyciu konstruktu sterowania przepływem, który wiąże zmiennej lokalnej/stałe, można użyć _ go zignorować. Na przykład, jeśli chcesz iteracyjne sekwencję bez konieczności dostępu do swoich członków:

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

Jeśli wiązanie przypadki krotka w instrukcji switch, podkreślenia może pracować jako zamiennika, jak w tym przykład (skrócony z jednego w The Swift Programming Language):

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

Wspaniały opis, dziękuję, proszę pana! –

+1

Myślę, że po prostu zapomniałeś o bardzo dobrym użyciu. Czasami interesuje Cię tylko ** liczba ** obiektów w tablicy lub słowniku i * nie * interesuje rzeczywistej wartości. Więc robisz coś w rodzaju 'dla _ w someArray {do stuff}'. Zwykle, gdy zależy Ci na wartości, będzie to "dla obiektu w someArray {do stuff}' – Honey

+0

Dobra sugestia. Dodałem go i kilka innych. – rickster

1

Od Swift 3 określanie nazw parametrów w wywołaniach funkcji stało się obowiązkowe - nawet dla pierwszego. Tak więc, ponieważ może to spowodować ogromny problem dla kodu napisanego w Swift 2, możesz użyć podkreślenia na deklaracji, aby zapobiec konieczności zapisywania nazwy parametru podczas rozmowy. W tym przypadku mówi się "nie przejmuj się zewnętrzną nazwą parametru". Gdzie zewnętrzna nazwa parametru jest tym, co nazywasz parametrami poza funkcją (na żądanie), nie wewnątrz. Te zewnętrzne nazwy parametrów są nazywane etykietami argumentów. http://ericasadun.com/2016/02/09/the-trouble-with-argument-labels-some-thoughts/ ... zobacz, jak parametr otrzymuje dwie nazwy? no cóż, pierwszy jest tam, gdzie idzie znak podkreślenia. Mam nadzieję, że to pomoże, i zapytaj, czy nadal nie rozumiesz.

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

_ jest symbolem zastępczym dla nazwy parametru. W twoim przykładzie nazywasz je inaczej, w drugiej funkcji musisz wpisać nazwę parametru a: 1.

Konwencja nazw funkcji Swift to funcName(param1:param2:), a jako symbol zastępczy potrzebny jest _ do utworzenia nazwy funkcji.

W imię, nazwisko jest

divmod(_:_:) 

Podczas gdy drugi jest

divmod(a:b:) 
Powiązane problemy