我是Swift的新手,我已经通过一些教程,其中许多教程使用相同的名称多次定义一个函数。
我已经习惯了其他编程语言,否则就无法完成,否则会引发错误。
因此,我检查了官方Swift Manual,并检查了override关键字,看看我能从中获得什么,但仍然无法理解以下代码:
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "MyTestCell")
cell.textLabel?.text = "Row #\(indexPath.row)"
cell.detailTextLabel?.text = "Subtitle #\(indexPath.row)"
return cell
}
从我所看到的函数tableView设置在第1行以及第5行中,我注意到的唯一区别是第一个tableView函数返回Int
而第二个返回{ {1}}(UITableViewCell)。
在这种情况下,我从结果中看到第二个函数没有覆盖第一个函数。
这是什么意思,为什么可以在不覆盖它的情况下使用相同的名称多次定义一个函数?
答案 0 :(得分:24)
如果它们具有不同的类型,或者可以通过其外部参数参数标签区分它们,则可以定义具有相同名称的两个函数。函数的类型由括号中的参数类型组成,后跟->
,后跟返回类型。请注意,参数标签不是函数Type的一部分。 (但请参阅下面的更新。)
例如,以下函数具有相同的名称且属于(Int, Int) -> Int
类型:
// This:
func add(a: Int, b: Int) -> Int {
return a + b
}
// Is the same Type as this:
func add(x: Int, y: Int) -> Int {
return x + y
}
这会产生编译时错误 - 将标签从a:b:
更改为x:y:
不会区分这两个功能。 (但请参阅下面的更新。)
以Web先生的功能为例:
// Function A: This function has the Type (UITableView, Int) -> Int
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { ... }
// Function B: This function has the Type (UITableView, NSIndexPath) -> UITableViewCell
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { ... }
// Function C: This made up function will produce a compile-time error because
// it has the same name and Type as Function A, (UITableView, Int) -> Int:
func tableView(arg1: UITableView, arg2: Int) -> Int { ... }
上面的函数A和函数B不会发生冲突,因为它们具有不同的类型。 上面的函数A和函数C 执行冲突,因为它们具有相同的类型。如果类型保持不变,则更改参数标签不会解决冲突。 (请参阅下面的更新。)
override
完全是一个不同的概念,我认为其他一些答案涵盖了它,所以我会跳过它。
更新:我上面写的一些内容不正确。确实,函数的参数标签不是它的类型定义的一部分,但是它们可以用于区分具有相同类型的两个函数,只要该函数具有不同的外部标签,使得编译器可以知道哪个您调用它时试图调用的函数。例如:
func add(a: Int, to b: Int) -> Int { // called with add(1, to: 3)
println("This is in the first function defintion.")
return a + b
}
func add(a: Int, and b: Int) -> Int { // called with add(1, and: 3)
println("This is in the second function definition")
return a + b
}
let answer1 = add(1, to: 3) // prints "This is in the first function definition"
let answer2 = add(1, and: 3) // prints "This is in the second function definition"
因此,在函数定义中使用外部标签将允许编译具有相同名称和相同类型的函数。因此,只要编译器可以通过类型或外部签名标签区分它们,您似乎可以编写具有相同名称的多个函数。我不认为内部标签很重要。 (但如果我错了,我希望有人会纠正我。)
答案 1 :(得分:7)
您正在考虑功能重载。
摘自Apple文档here:
您可以通过提供来重载通用函数或初始化程序 对类型参数的不同约束,要求或两者 泛型参数子句。当你调用一个重载的泛型 函数或初始化程序,编译器使用这些约束 解析要调用的重载函数或初始值设定项。
例如:
protocol A { }
protocol B { }
class A1: A { }
class A2: A { }
class B1: B { }
class B2: B { }
func process<T: A>(value: T)
{
// process values conforming to protocol A
}
func process<T: B>(value: T)
{
// process values conforming to protocol B
}
或:
func process(value: Int)
{
// process integer value
}
func process(value: Float)
{
// process float value
}
这种混乱很常见,特别是如果你是第一次从Objective-C迁移到Swift。您应该阅读有关参数名称here。
的信息答案 2 :(得分:5)
在Swift中,与Objective-C一样,函数的参数构成定义的一部分。没有两个名为tableView
的函数,有一个名为tableView(tableView:, numberOfRowsInSection:)
的函数和一个名为tableView(tableView:, cellForRowAtIndexPath:)
的函数
答案 3 :(得分:0)
功能不同,它们是不同的。因为他们不会采取相同的论点并返回不同的东西。如果您不了解泛型,这是一个简单的解释。