具有相同名称的多个功能

时间:2022-03-07 09:36:48

I'm new to Swift and I've been going thru some tutorials and many of them define a function more than once with the same name.

我是Swift的新手,我一直在通过一些教程,其中许多教程使用相同的名称多次定义一个函数。

I'm used to other programming languages where this cannot be done otherwise it throws an error.

我已经习惯了其他编程语言,否则就无法完成,否则会抛出错误。

Therefore I've checked the official Swift Manual and also checked the override keyword to see what I could get out of it, but still I cannot understand the following code:

因此,我检查了正式的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
}

From what I can see the function tableView is set in line #1 as well as in line #5, the only difference I noticed is that the first tableView function returns an Int and the second one returns an Object (UITableViewCell).

从我所看到的函数tableView在第1行以及第5行中设置,我注意到的唯一区别是第一个tableView函数返回一个Int,第二个返回一个Object(UITableViewCell)。

In this case I see from the result the second function is NOT overriding the first one.

在这种情况下,我从结果中看到第二个函数不会覆盖第一个函数。

What does this mean and why is it possible to define a function more than once with the same name without overriding it?

这是什么意思,为什么可以使用相同的名称多次定义一个函数而不覆盖它?

4 个解决方案

#1


22  

You are allowed to define two functions with the same name if they have different Types, or if they can be distinguished by their external parameter argument labels. The Type of a function is composed of the parameter Types in parentheses, followed by ->, followed by the return Type. Note that the argument labels are NOT a part of the function's Type. (But see UPDATE below.)

如果它们具有不同的类型,或者可以通过其外部参数参数标签区分它们,则可以定义具有相同名称的两个函数。函数的类型由括号中的参数类型组成,后跟 - >,后跟返回类型。请注意,参数标签不是函数Type的一部分。 (但请参阅下面的更新。)

For example, the following functions both have the same name and are of Type (Int, Int) -> Int:

例如,以下函数都具有相同的名称,并且是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
}

This will produce a compile-time error - changing the labels from a:b: to x:y: does not distinguish the two functions. (But see UPDATE below.)

这将产生编译时错误 - 将标签从a:b:更改为x:y:不区分这两个函数。 (但请参阅下面的更新。)

Using Mr. Web's functions as examples:

以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 { ... }

Function A and Function B above do not conflict because they are of different Types. Function A and Function C above do conflict because they have the same Type. Changing the parameter labels does not resolve the conflict if the Types remain the same. (See UPDATE below.)

上面的函数A和函数B不冲突,因为它们具有不同的类型。上面的函数A和函数C发生冲突,因为它们具有相同的类型。如果类型保持不变,则更改参数标签不能解决冲突。 (见下面的更新。)

override is a different concept altogether, and I think some of the other answers cover it, so I'll skip it.

覆盖是一个完全不同的概念,我认为其他一些答案涵盖了它,所以我会跳过它。

UPDATE: Some of what I wrote above is incorrect. It is true that a function's parameter labels are not a part of it's Type definition, but they can be used to distinguish two functions that have the same Type, so long as the function has external labels that are different such that the compiler can tell which function you are trying to call when you invoke it. Example:

更新:我上面写的一些内容不正确。确实,函数的参数标签不是它的类型定义的一部分,但是它们可以用于区分具有相同类型的两个函数,只要该函数具有不同的外部标签,使得编译器可以分辨哪个您调用它时尝试调用的函数。例:

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"

So, the use of external labels in a function definition will allow functions with the same name and of the same type to compile. So, it appears that you can write multiple functions with the same name so long as the compiler can distinguish them by their types or by their external signature labels. I don't think internal labels matter. (But I hope someone will correct me if I'm wrong.)

因此,在函数定义中使用外部标签将允许编译具有相同名称和相同类型的函数。因此,只要编译器可以通过类型或外部签名标签区分它们,您似乎可以编写具有相同名称的多个函数。我不认为内部标签很重要。 (但如果我错了,我希望有人会纠正我。)

#2


6  

You're thinking of function overloading.

你在考虑函数重载。

An excerpt from the Apple documentation here:

摘自Apple文档:

You can overload a generic function or initializer by providing different constraints, requirements, or both on the type parameters in the generic parameter clause. When you call an overloaded generic function or initializer, the compiler uses these constraints to resolve which overloaded function or initializer to invoke.

您可以通过在generic参数子句中的类型参数上提供不同的约束,要求或两者来重载泛型函数或初始化函数。当您调用重载的泛型函数或初始化程序时,编译器使用这些约束来解析要调用的重载函数或初始化程序。

For example:

例如:

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
}

or:

要么:

func process(value: Int)
{
    // process integer value
}

func process(value: Float)
{
    // process float value
}

This is just typical confusion that might arise during an Objective-C to Swift transition. You should read about parameter names here.

这只是在Objective-C到Swift过渡期间可能出现的典型混淆。你应该在这里阅读参数名称。

#3


3  

In Swift, as in Objective-C, the parameters of a function form part of the definition. There aren't two functions called tableView, there is one function called tableView(tableView:, numberOfRowsInSection:) and one called tableView(tableView:, cellForRowAtIndexPath:)

在Swift中,与Objective-C一样,函数的参数构成定义的一部分。没有两个函数叫做tableView,有一个叫做tableView的函数(tableView:,numberOfRowsInSection :)和一个叫做tableView的函数(tableView:,cellForRowAtIndexPath :)

#4


0  

The functions aren't the same they are different . Because they don't take the same arguments and return different things . This is the simple explanation if you don't understand generics.

它们的功能并不相同。因为他们不采用相同的论点并返回不同的东西。如果您不了解泛型,这是一个简单的解释。

#1


22  

You are allowed to define two functions with the same name if they have different Types, or if they can be distinguished by their external parameter argument labels. The Type of a function is composed of the parameter Types in parentheses, followed by ->, followed by the return Type. Note that the argument labels are NOT a part of the function's Type. (But see UPDATE below.)

如果它们具有不同的类型,或者可以通过其外部参数参数标签区分它们,则可以定义具有相同名称的两个函数。函数的类型由括号中的参数类型组成,后跟 - >,后跟返回类型。请注意,参数标签不是函数Type的一部分。 (但请参阅下面的更新。)

For example, the following functions both have the same name and are of Type (Int, Int) -> Int:

例如,以下函数都具有相同的名称,并且是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
}

This will produce a compile-time error - changing the labels from a:b: to x:y: does not distinguish the two functions. (But see UPDATE below.)

这将产生编译时错误 - 将标签从a:b:更改为x:y:不区分这两个函数。 (但请参阅下面的更新。)

Using Mr. Web's functions as examples:

以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 { ... }

Function A and Function B above do not conflict because they are of different Types. Function A and Function C above do conflict because they have the same Type. Changing the parameter labels does not resolve the conflict if the Types remain the same. (See UPDATE below.)

上面的函数A和函数B不冲突,因为它们具有不同的类型。上面的函数A和函数C发生冲突,因为它们具有相同的类型。如果类型保持不变,则更改参数标签不能解决冲突。 (见下面的更新。)

override is a different concept altogether, and I think some of the other answers cover it, so I'll skip it.

覆盖是一个完全不同的概念,我认为其他一些答案涵盖了它,所以我会跳过它。

UPDATE: Some of what I wrote above is incorrect. It is true that a function's parameter labels are not a part of it's Type definition, but they can be used to distinguish two functions that have the same Type, so long as the function has external labels that are different such that the compiler can tell which function you are trying to call when you invoke it. Example:

更新:我上面写的一些内容不正确。确实,函数的参数标签不是它的类型定义的一部分,但是它们可以用于区分具有相同类型的两个函数,只要该函数具有不同的外部标签,使得编译器可以分辨哪个您调用它时尝试调用的函数。例:

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"

So, the use of external labels in a function definition will allow functions with the same name and of the same type to compile. So, it appears that you can write multiple functions with the same name so long as the compiler can distinguish them by their types or by their external signature labels. I don't think internal labels matter. (But I hope someone will correct me if I'm wrong.)

因此,在函数定义中使用外部标签将允许编译具有相同名称和相同类型的函数。因此,只要编译器可以通过类型或外部签名标签区分它们,您似乎可以编写具有相同名称的多个函数。我不认为内部标签很重要。 (但如果我错了,我希望有人会纠正我。)

#2


6  

You're thinking of function overloading.

你在考虑函数重载。

An excerpt from the Apple documentation here:

摘自Apple文档:

You can overload a generic function or initializer by providing different constraints, requirements, or both on the type parameters in the generic parameter clause. When you call an overloaded generic function or initializer, the compiler uses these constraints to resolve which overloaded function or initializer to invoke.

您可以通过在generic参数子句中的类型参数上提供不同的约束,要求或两者来重载泛型函数或初始化函数。当您调用重载的泛型函数或初始化程序时,编译器使用这些约束来解析要调用的重载函数或初始化程序。

For example:

例如:

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
}

or:

要么:

func process(value: Int)
{
    // process integer value
}

func process(value: Float)
{
    // process float value
}

This is just typical confusion that might arise during an Objective-C to Swift transition. You should read about parameter names here.

这只是在Objective-C到Swift过渡期间可能出现的典型混淆。你应该在这里阅读参数名称。

#3


3  

In Swift, as in Objective-C, the parameters of a function form part of the definition. There aren't two functions called tableView, there is one function called tableView(tableView:, numberOfRowsInSection:) and one called tableView(tableView:, cellForRowAtIndexPath:)

在Swift中,与Objective-C一样,函数的参数构成定义的一部分。没有两个函数叫做tableView,有一个叫做tableView的函数(tableView:,numberOfRowsInSection :)和一个叫做tableView的函数(tableView:,cellForRowAtIndexPath :)

#4


0  

The functions aren't the same they are different . Because they don't take the same arguments and return different things . This is the simple explanation if you don't understand generics.

它们的功能并不相同。因为他们不采用相同的论点并返回不同的东西。如果您不了解泛型,这是一个简单的解释。