具有相同名称的多个function
我是Swift新手,我一直在通过一些教程,其中许多人定义了一个以上的同名function。
我已经习惯了其他的编程语言,否则就会抛出一个错误。
因此我检查了官方的Swift手册 ,并且检查了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
,第二个返回一个Object
(UITableViewCell)。
在这种情况下,我从结果中看到第二个函数不是覆盖第一个函数。
这是什么意思,为什么可以用相同的名字多次定义一个函数而不重写呢?
您可以定义两个具有相同名称的函数(如果它们具有不同的types),或者可以通过其外部参数参数标签来区分它们。 函数的types由括号中的参数types组成,后跟->
,然后是返回types。 请注意,参数标签不是函数types的一部分。 (但请参阅下面的更新。)
例如,以下函数具有相同的名称并且是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为例:
// 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不会冲突,因为它们是不同的types。 上面的函数A和函数C由于具有相同的types而发生冲突。 如果types保持不变,更改参数标签不会解决冲突。 (请参阅下面的更新。)
override
是一个完全不同的概念,我认为其他答案也包含了它,所以我会跳过它。
更新:我上面写的一些是不正确的。 确实,函数的参数标签不是它的types定义的一部分,但是它们可以用来区分两个具有相同types的函数,只要该函数具有不同的外部标签,以便编译器可以知道哪个函数,当你调用它时,你正试图调用它。 例:
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"
因此,在函数定义中使用外部标签将允许编译具有相同名称和相同types的函数。 因此,只要编译器可以通过它们的types或外部签名标签来区分它们,就可以编写多个具有相同名称的函数。 我不认为内部标签很重要。 (但是我希望有人会纠正我,如果我错了。)
你正在考虑函数重载 。
苹果文档摘录如下:
您可以通过在通用参数子句中的types参数上提供不同的约束,要求或两者来重载通用函数或初始化程序。 当您调用重载的generics函数或初始值设定项时,编译器将使用这些约束来parsing要调用的重载函数或初始值设定项。
例如:
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过渡期间可能出现的典型混淆。 你应该在这里阅读关于参数名称。
在Swift中,和Objective-C一样,函数的参数构成了定义的一部分。 有没有两个函数称为tableView
,有一个函数称为tableView(tableView:, numberOfRowsInSection:)
和一个名为tableView(tableView:, cellForRowAtIndexPath:)
function是不一样的,他们是不同的。 因为他们不采取相同的论点,并返回不同的东西。 如果你不懂generics,这是简单的解释。