Đại diện _ gạch dưới trong Tài liệu tham khảo Swift là gì?


144

Trong phần tài liệu tham khảo của các tài liệu của Apple có rất nhiều trường hợp về loại điều này:

func runAction(_action: SKAction!)

Mục tiêu-C 'tương đương' của điều này là:

- (void)runAction:(SKAction *)action

Tôi nhận ra rằng điều quan trọng là (trong tài liệu tham khảo Swift) có một khoảng trắng sau dấu gạch dưới và "hành động" được viết bằng chữ in nghiêng.

Nhưng tôi không thể hiểu điều này đang cố gắng truyền đạt. Vì vậy, có lẽ câu hỏi là ... có một tài liệu tham khảo cho các quy ước được sử dụng trong các tài liệu tham khảo?

- đây là trang tôi đang tham khảo trong tài liệu tham khảo này để sử dụng gạch dưới: https://developer.apple.com/documentation/spritekit/sknode#//apple_Vf/occ/instm/SKNode/runAction

Cập nhật

Swift 3 đã thực hiện một số thay đổi về cách sử dụng và đặt tên tham số hàm / phương thức và nhãn đối số. Điều này có sự phân nhánh về câu hỏi này và câu trả lời của nó. @Rickster thực hiện một công việc tuyệt vời để trả lời một câu hỏi khác về _underscores trong các chức năng giúp loại bỏ phần lớn vấn đề này, tại đây: Tại sao tôi cần gạch dưới nhanh chóng?


3
Được gắn thẻ với [underscore.js] ??
Martin R

3
Tài liệu này tuân theo quy ước toán học sử dụng chữ nghiêng cho tên biến. Ví dụ: sin² a + cos² a = 1.
cướp mayoff

Câu trả lời:


116

Cả hai câu trả lời đều đúng nhưng tôi muốn làm rõ hơn một chút.

_được sử dụng để sửa đổi hành vi tên tham số bên ngoài cho các phương thức .

Trong phần Tên tham số cục bộ và bên ngoài cho phương thức của tài liệu, nó nói:

Swift đặt tên tham số đầu tiên trong phương thức theo tên tham số cục bộ theo mặc định và đặt tên tham số thứ hai và tiếp theo cả tên tham số cục bộ và bên ngoài theo mặc định.

Mặt khác, các chức năng theo mặc định không có tên tham số bên ngoài.

Ví dụ, chúng ta có foo()phương thức này được định nghĩa trong lớp Bar:

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

Khi bạn gọi foo(), nó được gọi như thế bar.foo("Hello", s2: "World").

Nhưng , bạn có thể ghi đè hành vi này bằng cách sử dụng _ở phía trước s2nơi nó được khai báo.

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

Sau đó, khi bạn gọi foo, nó có thể được gọi đơn giản như bar.foo("Hello", "World")không có tên của tham số thứ hai.

Quay lại trường hợp của bạn, runActionlà một phương pháp vì SKNoderõ ràng nó liên quan đến loại . Do đó, việc đặt _tham số trước actioncho phép bạn gọi runActionmà không cần tên bên ngoài.

Cập nhật cho Swift 2.0

Hàm và phương thức hiện hoạt động theo cùng một cách về mặt khai báo tên đối số cục bộ và bên ngoài.

Các hàm bây giờ được gọi bằng cách sử dụng tên tham số bên ngoài theo mặc định, bắt đầu từ tham số thứ 2. Quy tắc này chỉ áp dụng cho mã Swift thuần túy.

Vì vậy, bằng cách cung cấp _trước một hàm , người gọi sẽ không phải chỉ định tên tham số bên ngoài, giống như những gì bạn sẽ làm cho một phương thức .


9
Nhầm lẫn, nếu _viết trước tham số thứ hai, câu trả lời của bạn rõ ràng là đủ; Điều gì xảy ra nếu trong func runAction(_action: SKAction!), _nằm trước tham số đầu tiên hoặc nếu bạn viết mã sau func foo(_ s1: String) { // your code }Xcode sẽ đưa ra cảnh báo, nhưng có rất nhiều mã như func bringSubviewToFront(_ view: UIView)trong tài liệu tham khảo, tại sao?
Will Zhang

10
về cơ bản, nó làm điều này không có lý do và chỉ khiến mọi người bối rối. tuyệt vời.
botbot

2
Một dấu gạch dưới được gọi là 'Wildcard Pattern' developer.apple.com/l
Library / ios / document / Swift / Conceptionual / Kẻ

@Wyatt Zhang, tài liệu nói, việc sử dụng _tham số đầu tiên là không liên quan. Tôi có thể đưa ra một giả định, rằng các nhà thiết kế nghĩ rằng nó rõ ràng là đủ cho mã của bạn và không dễ đọc, hoàn toàn ngược lại, nó làm hỏng mã. Vì vậy, bạn nhận được cảnh báo. Tham chiếu có mục tiêu ngược lại: nó phải rõ ràng nhất có thể - vì vậy dấu gạch dưới của tham số đầu tiên được đề cập cho phương pháp MERYI. Điều đó sẽ giải thích mọi thứ)
Dmitry Gryazin

4
Điều quan trọng cần lưu ý là Swift 3.0 thay đổi mọi thứ. Tất cả các nhãn là bắt buộc, trừ khi bạn chỉ định khác. Vì vậy, -trước khi tham số đầu tiên không còn là ngoại lai. Ví dụ: override func viewWillAppear(_ animated: Bool)tín hiệu rằng người gọi (mã Objective-C) sẽ không sử dụng nhãn tham số
Ông T

85

Dấu gạch dưới là mã thông báo chung được sử dụng để chỉ ra giá trị bị loại bỏ.

Trong trường hợp cụ thể này, điều đó có nghĩa là hàm sẽ được gọi runAction(argument)thay vìrunAction(action:argument)

Trong các bối cảnh khác, nó có ý nghĩa tương tự khác, ví dụ:

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

Điều đó có nghĩa là chúng tôi chỉ muốn thực hiện khối 5 lần và chúng tôi không quan tâm đến chỉ mục trong khối.

Trong ngữ cảnh này:

let (result, _) = someFunctionThatReturnsATuple()

Điều đó có nghĩa là chúng ta không quan tâm yếu tố thứ hai của bộ dữ liệu là gì, chỉ là yếu tố thứ nhất.


Vì vậy, trong trường hợp này, đối số (một hành động) là một lựa chọn?
Bối rối

1
Không, nó làm cho tên tham số bên ngoài (hành động :) trong trường hợp này bị trống, do đó bị bỏ qua. Đối số vẫn là bắt buộc, nó chỉ không được gắn thẻ với hành động :.
David Berry

4
Câu trả lời thực sự là sự kết hợp giữa câu trả lời của @ dasblinkenlight và của tôi. Ông giải quyết trường hợp cụ thể này chính xác hơn, trong khi của tôi giải quyết câu hỏi rộng hơn, _ có nghĩa là gì?
David Berry

4
Bạn cũng có thể sử dụng ký hiệu loại bỏ cho các số rất lớn để làm cho chúng dễ đọc hơn như thế nàylet pi = 3.141_592_653_59
SMP

thật thú vị, bạn cũng có thể sử dụng nó để làm cho những con số rất lớn không thể đọc được, nhưlet pi = 3.1_4_15_92___63
David Berry

15

Vì Swift 3 nên tất cả các nhãn đối số được yêu cầu theo mặc định .

Bạn có thể buộc IDE để ẩn nhãn đối số _.

func foo(a: String) {
}

func foo2(_ a: String) {
}

được gọi foo(a: "abc")foo2("abc")

Lưu ý: Điều này có thể được sử dụng chỉ khi anhãn (bên ngoài) lập luận(nội bộ) tên biến cùng một lúc. Nó tương đương - func foo(a a: String)sẽ không chấp nhận _.

Tại sao Apple sử dụng nó?

Bạn có thể thấy Apple đang sử dụng nó trên API. Các thư viện của Apple vẫn được viết bằng Objective-C (nếu không, dù sao họ cũng chia sẻ cùng tên hàm, được thiết kế cho cú pháp Objective-C)

Các hàm như applicationWillResignActive(_ application: UIApplication)sẽ có tên tham số dự phòngapplication , vì đã có ứng dụng trong tên hàm của nó.

Ví dụ của bạn

func runAction(_ action: SKAction!)sẽ được gọi mà không cần_đánh dấu như runAction(action:). Tên tham số actionsẽ là dự phòng vì đã có một tên trong tên hàm. Đó là mục đích và tại sao nó ở đó.


13

Một định danh ở phía trước khai báo tham số xác định tên tham số bên ngoài . Đây là tên phải được người gọi cung cấp khi gọi hàm:

func someFunction(externalParameterName localParameterName: Int)

Swift cung cấp tên bên ngoài tự động cho bất kỳ tham số mặc định nào bạn xác định, nếu bạn không tự cung cấp tên bên ngoài. Sử dụng dấu gạch dưới cho tên tham số bên ngoài sẽ loại bỏ hành vi này:

Bạn có thể từ chối hành vi này bằng cách viết dấu gạch dưới ( _) thay vì tên bên ngoài rõ ràng khi bạn xác định tham số.

Bạn có thể đọc thêm về hành vi này trong phần Tên bên ngoài cho tham số với giá trị mặc định tại đây .


vì vậy ... hãy để tôi xem liệu sự mờ nhạt của tôi có đúng không. Trong ví dụ này, tôi nên đặt tên biến / hằng tham số của mình là "hành động" và gán nó cho SKAction mà tôi muốn chạy bởi hàm này và Swift tự động đặt tên cho tham số mặc định là "hành động". TUY NHIÊN, nếu tôi muốn tùy chỉnh tên hành động này, tôi phải sử dụng dấu gạch dưới trong cách gọi hàm?
Bối rối

4
@Confuse Hiểu biết của tôi là SKcác nhà thiết kế không muốn bạn viết actionhai lần, vì "hành động" đã là một phần của tên hàm. Nói cách khác, họ không muốn bạn viết sprite.runAction(action:moveGroundSpritesForever). Mục đích của các tên tham số bên ngoài là làm cho mã của bạn "đọc như một câu"; sử dụng actionhai lần sẽ đánh bại mục đích của điều đó.
dasblinkenlight

Một số đèn bật sáng trong bóng tối. Tôi nghĩ rằng tôi nhận được nó. Tính năng này của ngôn ngữ nhằm mục đích làm cho các chức năng gọi trong Swift trông rất giống với cách bạn gọi một phương thức với các tham số trong Objective-C. Có lẽ.
Bối rối

1
Tuy nhiên, dấu gạch dưới có thể được sử dụng để bằng cách nào đó từ chối có các tên tham số bên ngoài này cho các tham số được xác định bằng một giá trị mặc định ... chỉ chưa thấy cách thực hiện. Sẽ tiếp tục tìm kiếm.
Bối rối

Vì vậy, ... tóm lại, nó chỉ đơn giản chuyển đổi giữa các tham số được đặt tên và tham số thứ tự, do đó bạn có thể dễ dàng chuyển đổi giữa foo.bar(param: 'fiddle')foo.bar('fiddle') LƯU Ý: chỉ với một đối số, nó thực sự không trở nên rõ ràng ... nhưng với nhiều đối số, nó trở nên rất phù hợp: foo.bar(param1: 'fiddle', param2: 'dee') vs foo.bar('fiddle','dee')
jrypkahauer

10

Tôi nghĩ rằng điều này buộc một quy ước trong Swift làm cho nó đọc gần hơn với object-c, phù hợp với các quy ước ca cao hơn. Trong objc bạn không (bên ngoài) đặt tên cho tham số đầu tiên của bạn. Thay vào đó, theo quy ước, bạn thường bao gồm tên bên ngoài trong phần sau của tên phương thức như sau:

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

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

Để thực hiện các cuộc gọi api Swift phù hợp với objc, bạn sẽ muốn chặn tên tham số bên ngoài của param đầu tiên.

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

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

2
Tôi thích lời giải thích này. học Obj-C trước, bạn đã dọn dẹp mọi thứ. Nó cũng nhấn mạnh tầm quan trọng của việc đặt tên Phương thức một cách thích hợp trong Swift, cụ thể là phần sau của tên Phương thức sẽ mô tả đối số đầu tiên, như trường hợp điển hình trong Obj-C. đồ tốt.
rrrrrenses

5

Trên thực tế, có một sự khác biệt giữa mã thực được sử dụng để xác định phương thức và khai báo phương thức trong tài liệu của Apple. Hãy lấy phương thức - addTarget: action: forControlEvents: của UIControl chẳng hạn, mã thực là: nhập mô tả hình ảnh ở đây

Nhưng trong tài liệu, nó xuất hiện như thế này (chú ý _ trước mục tiêu): nhập mô tả hình ảnh ở đây

Trong mã thực, _ được sử dụng để làm cho tên bên ngoài của tham số thứ hai hoặc tiếp theo không xuất hiện khi một phương thức được gọi, trong khi trong tài liệu, _ trước tên cục bộ của tham số cho biết rằng khi bạn gọi một phương thức hoặc hàm, bạn không nên cung cấp một tên bên ngoài.

Không có tên bên ngoài khi một hàm được gọi theo mặc định trừ khi bạn cung cấp tên riêng của bạn hoặc thêm # trước (không có khoảng trắng), ví dụ như tên địa phương của tham số, đây là cách chúng tôi sử dụng Clark_after : nhập mô tả hình ảnh ở đây

Và trong tài liệu, nó xuất hiện như thế này (chú ý ba _): nhập mô tả hình ảnh ở đây

Quy ước khai báo hàm giống như tôi đã mô tả cho phương thức.


1

Chỉ cần trực quan hơn.

nhập mô tả hình ảnh ở đây

Như bạn có thể thấy _chỉ cần bỏ qua một tên tham số cục bộ hoặc không.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.