Istnieje kilka niuansów dotyczących różnych przypadków użycia, ale ogólnie podkreślenie oznacza „zignoruj to”.
Podczas deklarowania nowej funkcji podkreślenie mówi Swiftowi, że parametr nie powinien mieć etykiety po wywołaniu - tak właśnie jest. 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. (Od wersji Swift 3, etykiety są domyślnie wymagane dla wszystkich argumentów). „Nazwa” to nazwa zmiennej dla tego argumentu, której 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 umożliwia użycie tego samego słowa zarówno dla etykiety argumentu zewnętrznego, jak i nazwy parametru wewnętrznego. To odpowiednik func myFunc(name name: Int)
.
Jeśli chcesz, aby funkcja była wywoływalna bez etykiet parametrów, użyj podkreślenia, _
aby etykieta była pusta / ignorowana. (W takim przypadku musisz podać nazwę wewnętrzną, jeśli chcesz mieć możliwość korzystania z parametru).
func myFunc(_ name: Int) // call it like myFunc(3)
W instrukcji przypisania podkreślenie oznacza „nie przypisuj niczego”. Możesz tego użyć, jeśli chcesz wywołać funkcję, która zwraca wynik, ale nie przejmuje się zwracaną wartością.
_ = someFunction()
Lub, jak w artykule, do którego utworzyłeś link, aby zignorować jeden element zwróconej krotki:
let (x, _) = someFunctionThatReturnsXandY()
Kiedy piszesz zamknięcie, które implementuje określony typ funkcji, możesz użyć podkreślenia, aby zignorować określone parametry.
PHPhotoLibrary.performChanges( { /* some changes */ },
completionHandler: { success, _ in // don't care about error
if success { print("yay") }
})
Podobnie podczas deklarowania funkcji, która przyjmuje protokół lub przesłania metodę nadklasy, można użyć nazw_
parametrów, aby zignorować parametry. Ponieważ protokół / nadklasa może również określać, że parametr nie ma etykiety, możesz nawet skończyć z dwoma podkreśleniami z rzędu.
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 związane z dwoma ostatnimi stylami: kiedy używasz konstrukcji sterującej przepływem, która wiąże lokalną zmienną / stałą, możesz _
ją zignorować. Na przykład, jeśli chcesz iterować sekwencję bez konieczności dostępu do jej elementów członkowskich:
for _ in 1...20 { // or 0..<20
// do something 20 times
}
Jeśli wiążesz przypadki krotek w instrukcji switch, podkreślenie może działać jako symbol wieloznaczny, jak w tym przykładzie (skróconym z jednego w języku programowania Swift ):
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")
}
Ostatnią rzeczą, która nie dość podobne, lecz ja to ponieważ (jak zauważył komentarzach) wydaje się prowadzić ludzi tutaj: podkreślenia w identyfikator - np var _foo
, func do_the_thing()
, struct Stuff_
- nic nie znaczy w szczególności Swift, ale ma kilka zastosowań wśród programistów.
Podkreślenia w nazwie są wyborem stylu, ale nie są preferowane w społeczności Swift, która ma silne konwencje dotyczące używania UpperCamelCase dla typów i lowerCamelCase dla wszystkich innych symboli.
Przedrostek lub sufiks nazwy symbolu podkreśleniem jest konwencją stylów, która w przeszłości służyła do odróżniania symboli prywatnych / przeznaczonych tylko do użytku wewnętrznego od eksportowanego interfejsu API. Jednak Swift ma do tego modyfikatory dostępu, więc ta konwencja jest ogólnie postrzegana jako nieidiomatyczna w Swift.
Kilka symboli z przedrostkami z podwójnym podkreśleniem ( func __foo()
) czai się w głębi SDK firmy Apple: Są to symbole (Obj) C zaimportowane do Swift przy użyciu NS_REFINED_FOR_SWIFT
atrybutu. Apple używa tego, gdy chce stworzyć „bardziej Swifty” wersję interfejsu API (Obj) C - na przykład, aby przekształcić metodę niezależną od typu w metodę ogólną . Muszą używać zaimportowanego interfejsu API, aby udoskonalona wersja Swift działała, więc używają go, __
aby był dostępny, ukrywając go przed większością narzędzi i dokumentacji.