Swift Referanslar'ın _ alt çizgi temsilcisi nedir?


144

Apple'ın dokümanlarının referans bölümünde bu tür şeylerin birçok örneği var:

func runAction(_action: SKAction!)

Bunun Objective-C 'eşdeğeri':

- (void)runAction:(SKAction *)action

Bana (Swift referansında) alt çizgiden sonra bir boşluk olması ve "eylem" italik yazılması önemli olabilir.

Ama bunun ne aktarmaya çalıştığını anlayamıyorum. Belki de soru şu ... referanslarda kullanılan sözleşmeler için bir referans var mı?

- işte bu altçizgi referansına atıfta bulunduğum sayfa: https://developer.apple.com/documentation/spritekit/sknode#//apple_ref/occ/instm/SKNode/runAction

Güncelleme

Swift 3, işlev / yöntem parametre adlarının ve bağımsız değişken etiketlerinin kullanılması ve adlandırılmasında bazı değişiklikler yaptı. Bunun bu soru ve cevabı hakkında sonuçları var. @Rickster, bunun çoğunu temizleyen işlevlerde _underscores hakkında farklı bir soruya cevap vermek için inanılmaz bir iş çıkarıyor: Burada neden hızlı bir şekilde alt çizgilere ihtiyacım var?


3
[Underscore.js] ile etiketlendi ??
Martin R

3
Doküman, değişken isimleri için italik yazım kurallarını takip ediyor. Örneğin: sin² a + cos² a = 1.
rob mayoff

Yanıtlar:


116

Her iki cevap da doğruydu ama biraz daha açıklığa kavuşturmak istiyorum.

_için kullanılan yöntemler için dış parametre adı davranışını değiştirmek .

In Yerel ve Yöntemler için harici Parametre Adları belgelerin bölümünde, diyor:

Swift, bir yöntemdeki ilk parametre adını varsayılan olarak yerel bir parametre adı verir ve ikinci ve sonraki parametre adlarına varsayılan olarak hem yerel hem de harici parametre adlarını verir .

Öte yandan, varsayılan olarak işlevlerin harici parametre adları yoktur.

Örneğin, bu foo()yöntem sınıfta tanımlanmıştır Bar:

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

Aradığınızda buna foo()denir bar.foo("Hello", s2: "World").

Ancak , bildirildiği yerin _önünde kullanarak bu davranışı geçersiz kılabilirsiniz s2.

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

Sonra, aradığınızda foo, bar.foo("Hello", "World")ikinci parametrenin adı olmadan basitçe çağrılabilir .

Sizin durumunuza geri dönersek, runActionbir yöntemdir, çünkü SKNodeaçıkçası türle ilişkilendirilmiştir . Bu nedenle, bir _before parametresi koymak, harici bir ad olmadan actionçağrı yapmanızı sağlar runAction.

Swift 2.0 Güncellemesi

İşlev ve yöntem artık yerel ve harici argüman adı bildirimi açısından aynı şekilde çalışmaktadır .

Fonksiyonlar artık 2. parametreden başlayarak varsayılan olarak harici parametre adı kullanılarak çağrılmaktadır. Bu kural yalnızca saf Swift kodu için geçerlidir.

Bu nedenle, _bir işlevin önüne bir giriş sağlayarak , arayanın bir yöntem için ne yapacağınız gibi harici parametre adı belirtmesi gerekmez .


9
Şaşkın, eğer _ikinci parametreden önce yazma, cevabınız açıkça yeterli; ne olursa func runAction(_action: SKAction!), _ilk parametre öncedir ya da aşağıdaki kodu yazarsanız func foo(_ s1: String) { // your code }Xcode size bir uyarı verecek, ancak bir çok kodun gibi orada func bringSubviewToFront(_ view: UIView)referans, neden mi?
Zhang

10
temelde bunu sebepsiz yapar ve sadece herkesi karıştırır. müthiş.
botbot

2
Alt

@Wyatt Zhang, doktor _, ilk parametre için kullanımının gereksiz olduğunu söylüyor . Bir varsayım yapabilirim, tasarımcıların kodunuz için açıkça yeterli olduğunu ve okunabilirliği etkilemediğini düşünürüm, aksine, kodu topraklar. Böylece uyarıyı alırsınız. Referansın zıt amacı vardır: mümkün olduğu kadar açık olmalıdır - bu nedenle HER parametrenin ilk parametresinin alt çizgisinden bahsedilir. Bu her şeyi açıklar)
Dmitry Gryazin

4
Swift 3.0'ın bazı şeyleri değiştirdiğine dikkat etmek önemlidir. Aksi belirtilmedikçe tüm etiketler gereklidir. Yani -ilk parametre daha önce artık yabancı değildir. Örneğin: override func viewWillAppear(_ animated: Bool)Arayanın (Objective-C kodu) parametre etiketi kullanmayacağını gösterir
Bay T

85

Alt çizgi, atılan bir değeri belirtmek için kullanılan genel bir simgedir.

Bu özel durumda, işlev runAction(argument)yerinerunAction(action:argument)

Diğer bağlamlarda başka benzer anlamları vardır, örneğin:

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

Bu, sadece bloğu 5 kez yürütmek istediğimiz ve blok içindeki dizini umursamadığımız anlamına gelir.

Bu içerikte:

let (result, _) = someFunctionThatReturnsATuple()

Bu, demetin ikinci elementinin ne olduğunu umursamadığımız anlamına gelir, sadece birincisi.


Peki bu durumda argüman (eylem) bir seçenek midir?
Confused

1
Hayır, bu durumda harici parametre adının (eylem :) boş olmasına ve dolayısıyla atlanmasına neden olur. Argüman hala gerekli, sadece eylemle etiketlenmiyor:
David Berry

4
Gerçek cevap @ dasblinkenlight'ın cevabı ve benimkinin bir kombinasyonudur. Bu özel durumu daha net bir şekilde ele alırken, benimki daha geniş soruyu ele alırken, _ ne anlama geliyor?
David Berry

4
Bunları daha okunabilir hale getirmek için çok büyük sayılar için de ıskarta işaretini kullanabilirsinizlet pi = 3.141_592_653_59
SMP

eğlenceli bir şekilde, çok büyük sayıları daha az okunabilir hale getirmek için de kullanabilirsinizlet pi = 3.1_4_15_92___63
David Berry

15

Swift 3'ten beri varsayılan olarak tüm bağımsız değişken etiketleri gereklidir .

IDE'yi ile bir bağımsız değişken etiketini gizlemeye zorlayabilirsiniz _.

func foo(a: String) {
}

func foo2(_ a: String) {
}

aradı foo(a: "abc")vefoo2("abc")

Not: Yalnızca bu kullanılabilir aolan (dış) argüman etiket ve (dahili) değişken adı aynı anda. Eşdeğerdir - func foo(a a: String)kabul etmeyecektir _.

Apple neden kullanıyor?

Apple'ın API genelinde kullandığını görebilirsiniz. Apple'ın kütüphaneleri hala Objective-C'de yazılmıştır (eğer değilse, Objective-C sözdizimi için tasarlanmış aynı işlev adlarını paylaşırlar)

Zaten işlevler , zaten uygulama olduğundan yedek parametre adına applicationWillResignActive(_ application: UIApplication)sahip olacaktırapplication 's işlev adı.

Örneğiniz

func runAction(_ action: SKAction!)aranmak olmadan 's _gibi işareti runAction(action:). İşlev adında zaten bir tane olduğundan parametre adı gereksizaction olur . Amaç bu ve neden orada.


13

Parametre bildiriminin önündeki bir tanımlayıcı harici bir parametre adı tanımlar . Bu, işlevi çağırırken arayan tarafından sağlanması gereken addır:

func someFunction(externalParameterName localParameterName: Int)

Kendiniz harici bir ad sağlamazsanız Swift, tanımladığınız herhangi bir varsayılan parametre için otomatik bir harici ad sağlar. Harici parametre adı için bir alt çizgi kullanmak bu davranıştan vazgeçer:

_Parametreyi tanımlarken açık bir harici ad yerine bir alt çizgi ( ) yazarak bu davranışı devre dışı bırakabilirsiniz .

Bu davranış hakkında daha fazla bilgiyi Varsayılan Değerleri Olan Parametreler için Harici Adlar bölümünde bulabilirsiniz .


öyleyse ... görelim bakalım hayal gücüm bu hakka sahip mi? Bu örnekte parametre değişkenimi / sabiti "action" olarak adlandırmalı ve bu fonksiyon tarafından çalıştırılmasını istediğim SKAction'a atamalıyım ve Swift otomatik olarak gerekli varsayılan parametreyi "action" olarak adlandırmalıdır. ANCAK, bu eylem özel ad vermek istiyorsanız ben fonksiyon çağrısında alt çizgi kullanmanız gerekir?
Confused

4
@Confused Benim anlayışım SKtasarımcıların actioniki kez yazmanızı istemediğidir , çünkü "eylem" zaten fonksiyonun adının bir parçasıdır. Başka bir deyişle, yazmanızı istemiyorlar sprite.runAction(action:moveGroundSpritesForever). Harici parametre adlarının amacı kodunuzu "bir cümle gibi okumak"; actioniki kez kullanmak bunun amacını bozacaktır.
dasblinkenlight

Karanlıkta bazı ışıklar yanıyordu. Sanırım anladım. Dilin bu özelliği, Swift'teki çağrı işlevlerinin Objective-C'deki parametrelerle bir yöntemi nasıl çağırdığınıza benzemesini sağlamayı amaçlamaktadır. Olabilir.
Confused

1
Ancak alt çizgi, varsayılan değerle tanımlanan parametreler için bu harici parametre adlarının bir şekilde devre dışı bırakılması için kullanılabilir ... henüz nasıl yapıldığını görmedim. Bakmaya devam edecek.
Confused

Yani ... kısaca, sadece adlandırılmış parametreler ve sıralı parametreler arasında geçiş yapar, böylece kolayca arasında geçiş yapabilirsiniz foo.bar(param: 'fiddle') ve foo.bar('fiddle') NOT: sadece bir argümanla gerçekten belirgin olmaz ... ama birden fazla argümanla çok alakalı hale gelir: foo.bar(param1: 'fiddle', param2: 'dee') vs foo.bar('fiddle','dee')
jrypkahauer

10

Sanırım bu Swift'te kakao konvansiyonlarını daha iyi karşılayan objektif-c'ye daha yakın okumasını sağlayan bir sözleşmeyi zorladı. Objc'de ilk parametrenizi (harici olarak) adlandırmazsınız. Bunun yerine, kural olarak, dış ad genellikle yöntem adının ikinci bölümüne şu şekilde eklenir:

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

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

Swift api çağrılarını objc ile tutarlı hale getirmek için ilk parametrenin dış parametre adını bastırmak isteyeceksiniz.

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

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

2
Bu açıklamayı seviyorum. önce Obj-C'yi öğrendikten sonra, bazı şeyleri temizlediniz. Ayrıca, Yöntemi Swift'te uygun şekilde adlandırmanın önemini de vurgulamaktadır, yani Yöntem adının ikinci kısmı, tipik olarak Obj-C'de olduğu gibi ilk argümanı tanımlamalıdır. iyi şeyler.
rrrrrraul

5

Aslında, bir yöntemi tanımlamak için kullanılan gerçek kod ile Apple dokümanlarında yöntem bildirimi arasında bir fark vardır. En alalım UIControl 'ler - addTarget: aksiyon: forControlEvents: örneğin metodu, gerçek kodudur: resim açıklamasını buraya girin

Ancak dokümanlarda şu şekilde görünür (hedeften önce _ dikkat edin): resim açıklamasını buraya girin

Gerçek kodda, bir yöntem çağrıldığında ikinci veya sonraki parametrenin dış adının görünmemesini sağlamak için kullanılır ; dokümanlardayken, bir parametrenin yerel adının bir yöntemi veya işlevi çağırdığınızda, bir yöntem veya işlevi çağırdığınızda harici ad.

Eğer kendi parametrenizi girmedikçe veya bir parametrenin yerel adından önce (boşluk olmadan) # eklemediğiniz sürece varsayılan olarak bir işlev çağrıldığında dış ad yoktur, örneğin dispatch_after'ı şu şekilde kullanırız : resim açıklamasını buraya girin

Ve dokümanlarda şu şekilde görünür (üçe dikkat edin _): resim açıklamasını buraya girin

İşlev bildirimi kuralı, yöntem için tanımladığımla aynıdır.


1

Daha görsel.

resim açıklamasını buraya girin

Gördüğünüz gibi _atlamayı yerel bir parametre adı olsun ya da olmasın.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.