在回答这个问题时,我们发现了一个调用标签是必需的init
.这在Swift中是正常的.
class Foo {
init(one: Int, two: String) { }
}
let foo = Foo(42, "Hello world") // Missing argument labels 'one:two:' in call
Run Code Online (Sandbox Code Playgroud)
然而,陌生人的力量在起作用:
extension Foo {
func run(one: String, two: [Int]) { }
}
foo.run(one: "Goodbye", two: []) // Extraneous argument label 'one:' in call
Run Code Online (Sandbox Code Playgroud)
要在此处使用参数标签,必须明确声明.
我没有在文档中看到非常详尽的解释所有这些内容.哪些类/实例/全局函数是必需的参数标签?是否始终使用参数标签导出和导入Obj-C方法?
Con*_*nor 43
所有init方法都需要参数名称:
var view = NSView(frame: NSRect(x: 10, y: 10, width: 50, height: 50))
class Foo {
init(one: Int, two: String) { }
}
let foo = Foo(one: 42, two: "Hello world")
Run Code Online (Sandbox Code Playgroud)
调用对象的所有方法都使用除第一个参数之外的所有参数名称:
extension Foo {
func run(one: String, two: [Int]) { }
}
foo.run("Goodbye", two: [])
Run Code Online (Sandbox Code Playgroud)
所有包括Swift和objective-c中的类函数都遵循相同的模式.您还可以显式添加外部名称.
extension Foo{
class func baz(one: Int, two: String){}
class func other(exOne one: Int, exTwo two: String){}
}
Foo.baz(10, two:"str")
Foo.other(exOne: 20, exTwo:"str")
Run Code Online (Sandbox Code Playgroud)
不是类函数的Swift函数不需要参数名称,但您仍然可以显式添加它们:
func bar(one: Int, two: String){}
bar(1, "hello")
Run Code Online (Sandbox Code Playgroud)
正如Bryan所说,当调用方法签名中具有参数名称的objective-c方法时,使Swift方法调用有意义.Init方法包括第一个参数,因为Swift将init方法从objective-c从initWith:...更改为Class(),因此第一个参数名称不再包含在方法名称中.
rav*_*ron 31
在将于2016年底发布的 Swift 3.0中,默认行为很简单:
您可以在Swift API设计指南中最简洁地找到这些规则.这一最新行为在SE-0056中提出,"在包括第一标签在内的所有参数上建立一致的标签行为",并在SR-961中实施.可以在"覆盖默认行为"中按如下所述更改默认行为.
在Swift 2.2中,外部参数标签存在的语言默认值已经改变,现在变得更加简单.默认行为可以总结如下:
可以在"覆盖默认行为"中按如下所述更改默认行为.
这些规则最好用一个例子来证明:
func printAnimal(animal: String, legCount: Int) {
let legNoun = legCount == 1 ? "leg" : "legs"
print("\(animal) has \(legCount) \(legNoun)")
}
struct Player {
let name: String
let lives: Int
init(name: String, lives: Int) {
self.name = name
self.lives = lives
}
func printCurrentScore(currentScore: Int, highScore: Int) {
print("\(name)'s score is \(currentScore). Their high score is \(highScore)")
}
}
// SWIFT 3.0
// In Swift 3.0, all argument labels must be included
printAnimal(animal: "Dog", legCount: 4)
let p = Player(name: "Riley", lives: 3)
p.printCurrentScore(currentScore: 50, highScore: 110)
// SWIFT 2.2
// In Swift 2.2, argument labels must be included or omitted in exactly the following way
// given the definition of the various objects.
printAnimal("Dog", legCount: 4)
let p = Player(name: "Riley", lives: 3)
p.printCurrentScore(50, highScore: 110)
// In Swift 2.2, none of the following will work
printAnimal(animal: "Dog", legCount: 4) // Extraneous argument label 'animal:' in call
let q = Player("Riley", lives: 3) // Missing argument label 'name:' in call
p.printCurrentScore(50, 110) // Missing argument label 'highScore:' in call
Run Code Online (Sandbox Code Playgroud)
对于任何方法或函数的任何参数,您可能会偏离语言的默认值,但样式指南会正确地警告您不要这样做,除非有充分的理由.
要添加一个通常不存在的外部参数标签 - 仅适用于Swift 2.2,因为Swift 3.0默认为每个参数分配外部标签 - 或更改外部参数标签 - 适用于两个版本 - 写入所需的外部参数local参数标签前的标签:
func printAnimal(theAnimal animal: String, legCount: Int) {
let legNoun = legCount == 1 ? "leg" : "legs"
print("\(animal) has \(legCount) \(legNoun)")
}
printAnimal(theAnimal: "Dog", legCount: 4)
Run Code Online (Sandbox Code Playgroud)
要删除通常有外部参数标签的外部参数标签,请使用特殊的外部参数标签_
:
func printAnimal(animal: String, _ legCount: Int) {
let legNoun = legCount == 1 ? "leg" : "legs"
print("\(animal) has \(legCount) \(legNoun)")
}
// SWIFT 3.0
printAnimal(theAnimal: "Dog", 4)
// SWIFT 2.2
printAnimal("Dog", 4)
Run Code Online (Sandbox Code Playgroud)
这些"默认覆盖"适用于任何方法或功能,包括初始化程序.
Two*_*aws 29
从Swift 3.0开始,这又发生了变化:除非您明确选择使用外部名称,否则所有方法,函数和初始化程序都需要所有参数的参数标签_
.这意味着像addChildViewController(_:)
现在写的方法如下:
func addChildViewController(_ childController: UIViewController)
Run Code Online (Sandbox Code Playgroud)
这是作为Swift Evolution过程的一部分提出并批准的,并在SR-961中实施.
Und*_*ndo 11
这是我通过阅读(相当稀疏的)文档并通过简单的实验来收集的内容:
Init方法总是需要它们的标签.像标签这样的初始化方法,因为它们清楚地表明你要调用的init方法.否则,这个:
FooBar(foos: 5)
Run Code Online (Sandbox Code Playgroud)
还有这个:
FooBar(bars: 5)
Run Code Online (Sandbox Code Playgroud)
看起来完全一样:
FooBar(5)
Run Code Online (Sandbox Code Playgroud)
这种情况无处不在 - 初始化方法是Swift中唯一的地方,它们都有相同的名称,但可能有不同的参数.这就是为什么...
函数,方法等(不是 init方法的任何东西)都省略了第一个标签 - 这是为了样式并减少无聊的重复性.代替
aDictionary.removeValueForKey(key: "four")
Run Code Online (Sandbox Code Playgroud)
我们有这个:
aDictionary.removeValueForKey("four")
Run Code Online (Sandbox Code Playgroud)
并且对具有两个参数的函数仍然具有相当不明确且易于阅读的参数.而不是
anArray.insert("zebras", 9)
Run Code Online (Sandbox Code Playgroud)
我们有一个更容易理解的阅读形式:
anArray.insert("zebras", atIndex: 9)
Run Code Online (Sandbox Code Playgroud)哪个看起来好多了.当我在WWDC时,这被吹捧为Swift的一个特征:Java风格的现代,简短的论点,而不会牺牲可读性.正如Bryan Chen的回答所示,这也简化了从Objective-C的过渡.
您可以#
在标签之前使用调用方法所需的参数标签.
例如:
func addLocation(latitude : Double, longitude : Double) { /*...*/ }
addLocation(125.0, -34.1) // Not clear
Run Code Online (Sandbox Code Playgroud)
可以像这样改进:
func addLocation(#latitude : Double, #longitude : Double) { /*...*/ }
addLocation(latitude: 125.0, longitude: -34.1) // Better
Run Code Online (Sandbox Code Playgroud)
(来自WWDC 2014 - 416 - 建筑现代框架,15分钟)
归档时间: |
|
查看次数: |
25477 次 |
最近记录: |