Ios Swift:只在返回类型上不同的方法重载
我一直看到Swift类定义了两种方法,它们的返回类型不同。我不习惯在允许的语言中工作(Java、C#等),所以我去寻找描述如何在Swift中工作的文档。我什么地方都没找到。我本以为斯威夫特的书中会有一整节关于它的内容。这在哪里有记录 下面是我正在谈论的一个例子(我使用的是Swift 2,FWIW): 测试:Ios Swift:只在返回类型上不同的方法重载,ios,swift,swift2,Ios,Swift,Swift2,我一直看到Swift类定义了两种方法,它们的返回类型不同。我不习惯在允许的语言中工作(Java、C#等),所以我去寻找描述如何在Swift中工作的文档。我什么地方都没找到。我本以为斯威夫特的书中会有一整节关于它的内容。这在哪里有记录 下面是我正在谈论的一个例子(我使用的是Swift 2,FWIW): 测试: 函数的类型由其参数的类型及其返回值的类型决定,编译器可以根据其类型消除类似命名函数的歧义-从您的示例: subscript(key: Int) -> Int { return
函数的类型由其参数的类型及其返回值的类型决定,编译器可以根据其类型消除类似命名函数的歧义-从您的示例:
subscript(key: Int) -> Int {
return 1
}
…具有类型(Int)->Int
subscript(key: Int) -> String {
return "hi"
}
func getSomething() -> String {
return "hey"
}
…具有类型(Int)->字符串
--因此,尽管它们的名称相似,编译器可以通过如何分配返回值(或者由于这是一个下标
,通过将什么值分配给该下标)来推断调用哪一个
继续:
func getSomething() -> Int {
return 2
}
…具有类型()->Int
subscript(key: Int) -> String {
return "hi"
}
func getSomething() -> String {
return "hey"
}
…具有类型()->字符串
注意:如果您没有向编译器提供足够的信息来推断您正在调用哪个函数,那么您可能会遇到麻烦,例如,如果您只是调用了getSomething()
,而没有对其返回值做任何处理,它会抱怨使用了不明确的“getSomething”
编辑-啊,我在您的示例代码中看到,您实际上提供了一个例子,在这种情况下:)通过将返回值赋给一个未指定类型的常量(让x=getSomething()
),编译器没有足够的信息来排序您调用的函数
编辑编辑-请注意,我从“编译器可以根据其类型消除类似命名函数的歧义”开始,函数名称由以下因素决定:(1)函数的标识符,以及(2)函数外部参数名称的标识符-例如,尽管以下两个函数都具有相同的类型和函数标识符,但它们是不同的函数,并且具有不同的函数名称,因为它们用于外部参数名称的标识符不同:
func getSomething(thing: String, howMany: Int) -> String
…的类型为(String,Int)->String
,名称为getSomething(uquo:howmount:)
…的类型为(String,Int)->String
,并命名为getSomething(uquo:howManyTimes:)
这在哪里有记录
至于下标
:
只要参数或返回类型与正在重载的不同,就可以在声明的类型中重载下标声明
一个类或结构可以根据需要提供尽可能多的下标实现,并且将根据值的类型或下标使用点下标括号中包含的值来推断要使用的适当下标
我找不到任何关于重载方法或函数的官方文档。但在Swift博客中:
请记住,即使两个签名的返回类型不同,Swift也允许函数重载
这是斯威夫特相当酷的一面。我目前正在一个泛型类中使用它来拥有多个下标。这里是我创建的一个操场,用于培训:
import Foundation
/*
Return Type Differentiation
This playground illustrates a rather useful capability of Swift: The ability to differentiate methods by return type; not just argument list.
In this example, we will set up multiple subscript() methods for an aggregator/façade class that will access the contained instances in
various ways, depending on the return type requested.
*/
// This class should win the igNoble prize for poitry.
struct A {
let poem: [String] = ["I'm a little teapot",
"bloody and cut.",
"This is my handle.",
"This is my "]
let multiplier: UInt32 = arc4random_uniform(100) // Just a random integer from 0 to 100.
}
// This class has a few different data types that are set at instantiation time, and one static instance of A
class B {
let stringProperty: String
let intProperty: Int = Int(arc4random_uniform(10))
let objectProperty: A = A()
init(_ string: String) {
self.stringProperty = string
}
// This will be used to demonstrate that we don't need to explicitly cast, if we only have one subscript method.
subscript(_ ignoredIndex: Int) -> A {
return self.objectProperty
}
}
// This class acts as a façade class. It provides an interface to its contained classes as if they were direct subscripts.
class C : Sequence {
let aArray: [B]
init() {
self.aArray = [B("hut"),B("butt")]
}
// You can have multiple subscript() methods, differentiated by return type.
subscript(_ index: Int) -> B {
return self.aArray[index]
}
subscript(_ index: Int) -> String {
return self.aArray[index].stringProperty
}
subscript(_ index: Int) -> UInt32 {
return (self[index] as A).multiplier
}
subscript(_ index: Int) -> Int {
return self.aArray[index].intProperty
}
subscript(_ index: Int) -> A {
return self.aArray[index].objectProperty
}
// These are not simple data return subscripts. In fact, there are no Float properties, so that one is made from whole cloth.
subscript(_ index: Int) -> Float {
return Float(self.aArray[index].intProperty) * Float((self[index] as A).multiplier)
}
subscript(_ index: Int) -> [String] {
var ret: [String] = []
let aInstance: B = self.aArray[index]
ret = aInstance[0].poem // No need for explicit casting if we only have one subscript.
ret[3] += self[index] + "." // This is allowed, as we know we're a String.
return ret
}
// You can only have one makeIterator() method.
func makeIterator() -> AnyIterator<[String]> {
var nextIndex = 0
// Return a "bottom-up" iterator for the list.
return AnyIterator() {
if nextIndex == self.aArray.count {
return nil
}
let ret: [String]! = self.aArray[nextIndex - 1].objectProperty.poem
nextIndex += 1
return ret
}
}
// You can have multiple methods with the same input signature, differentiated only by their output signature.
func returnIndexedElement(_ atIndex: Int) -> Int {
return self[atIndex] // Note no explicit casting is necessary, here.
}
func returnIndexedElement(_ atIndex: Int) -> UInt32 {
return self[atIndex]
}
func returnIndexedElement(_ atIndex: Int) -> A {
return self[atIndex]
}
func returnIndexedElement(_ atIndex: Int) -> B {
return self[atIndex]
}
func returnIndexedElement(_ atIndex: Int) -> Float {
return self[atIndex]
}
func returnIndexedElement(_ atIndex: Int) -> String {
return self[atIndex]
}
func returnIndexedElement(_ atIndex: Int) -> [String] {
return self[atIndex]
}
}
let mainObject = C()
// First, let's test the subscripts.
// We have 3 elements, so
let aObject1: A = mainObject[0]
let aObject2: B = mainObject[0]
let aString: String = mainObject[0]
let aPoem: [String] = mainObject[0]
let aInt: Int = mainObject[0]
let aUInt32 = mainObject[0] as UInt32
let aFloat = mainObject[0] as Float
// This will not work. You need to specify the type explicitly when using multiple subscripts, differentiated only by return type.
// let failObject = mainObject[0]
// However, this will work, because the class has only one subscript method defined.
let aObject2_Subscript = aObject2[0]
let aObject2_Poem = aObject2_Subscript.poem
// Next, test the accessor methods.
let bObject1: A = mainObject.returnIndexedElement(1)
let bObject2: B = mainObject.returnIndexedElement(1)
let bString: String = mainObject.returnIndexedElement(1)
let bPoem: [String] = mainObject.returnIndexedElement(1)
let bInt: Int = mainObject.returnIndexedElement(1)
let bUInt32 = mainObject.returnIndexedElement(1) as UInt32
let bFloat = mainObject.returnIndexedElement(1) as Float
// This will not work. You need to specify the type explicitly when using multiple methods, differentiated only by return type.
// let failObject = mainObject.returnIndexedElement(1)
<代码>导入基础
/*
返回型微分
这说明了Swift的一个相当有用的功能:能够根据返回类型区分方法;不仅仅是参数列表。
在本例中,我们将为一个aggregator/façade类设置多个subscript()方法,该类将访问中包含的实例
根据请求的返回类型,有多种方式。
*/
//这个班应该赢得不光彩的政治奖。
结构A{
让诗:[串]=[“我是一个小茶壶”,
“血迹斑斑。”,
“这是我的把手。”,
“这是我的”]
让乘法器:UInt32=arc4random_uniform(100)//只是一个从0到100的随机整数。
}
//这个类有几个在实例化时设置的不同数据类型,以及一个
B类{
let stringProperty:String
let intProperty:Int=Int(arc4random_uniform(10))
let objectProperty:A=A()
init(uString:string){
self.stringProperty=string
}
//这将用于证明,如果我们只有一个下标方法,则不需要显式强制转换。
下标(u-ignoredIndex:Int)->A{
返回self.objectProperty
}
}
//这个类充当一个façade类。它为其包含的类提供了一个接口,就像它们是直接下标一样。
C类:序列{
让aArray[B]
init(){
self.aArray=[B(“小屋”),B(“屁股”)]
}
//可以有多个subscript()方法,按返回类型区分。
下标(索引:Int)->B{
返回self.aArray[索引]
}
下标(u-index:Int)->字符串{
返回self.aArray[index].stringProperty
}
下标(u索引:Int)->UInt32{
返回(自[索引]作为)。乘数
}
下标(索引:Int)->Int{
返回self.aArray[index].intProperty
}
下标(u-index:Int)->A{
返回self.aArray[index].objectProperty
}
//这些不是简单的数据返回下标。事实上,并没有浮点属性,所以一个是由整个布料组成的。
下标(u-index:Int)->Float{
返回浮点(self.aArray[index].intProperty)*浮点((self[index]作为.multiplier)
}
下标(u索引:Int)->[字符串]{
变量ret:[字符串]=[]
让aInstance:B=self.aArray[index]
ret=aInstance[0]。诗
import Foundation
/*
Return Type Differentiation
This playground illustrates a rather useful capability of Swift: The ability to differentiate methods by return type; not just argument list.
In this example, we will set up multiple subscript() methods for an aggregator/façade class that will access the contained instances in
various ways, depending on the return type requested.
*/
// This class should win the igNoble prize for poitry.
struct A {
let poem: [String] = ["I'm a little teapot",
"bloody and cut.",
"This is my handle.",
"This is my "]
let multiplier: UInt32 = arc4random_uniform(100) // Just a random integer from 0 to 100.
}
// This class has a few different data types that are set at instantiation time, and one static instance of A
class B {
let stringProperty: String
let intProperty: Int = Int(arc4random_uniform(10))
let objectProperty: A = A()
init(_ string: String) {
self.stringProperty = string
}
// This will be used to demonstrate that we don't need to explicitly cast, if we only have one subscript method.
subscript(_ ignoredIndex: Int) -> A {
return self.objectProperty
}
}
// This class acts as a façade class. It provides an interface to its contained classes as if they were direct subscripts.
class C : Sequence {
let aArray: [B]
init() {
self.aArray = [B("hut"),B("butt")]
}
// You can have multiple subscript() methods, differentiated by return type.
subscript(_ index: Int) -> B {
return self.aArray[index]
}
subscript(_ index: Int) -> String {
return self.aArray[index].stringProperty
}
subscript(_ index: Int) -> UInt32 {
return (self[index] as A).multiplier
}
subscript(_ index: Int) -> Int {
return self.aArray[index].intProperty
}
subscript(_ index: Int) -> A {
return self.aArray[index].objectProperty
}
// These are not simple data return subscripts. In fact, there are no Float properties, so that one is made from whole cloth.
subscript(_ index: Int) -> Float {
return Float(self.aArray[index].intProperty) * Float((self[index] as A).multiplier)
}
subscript(_ index: Int) -> [String] {
var ret: [String] = []
let aInstance: B = self.aArray[index]
ret = aInstance[0].poem // No need for explicit casting if we only have one subscript.
ret[3] += self[index] + "." // This is allowed, as we know we're a String.
return ret
}
// You can only have one makeIterator() method.
func makeIterator() -> AnyIterator<[String]> {
var nextIndex = 0
// Return a "bottom-up" iterator for the list.
return AnyIterator() {
if nextIndex == self.aArray.count {
return nil
}
let ret: [String]! = self.aArray[nextIndex - 1].objectProperty.poem
nextIndex += 1
return ret
}
}
// You can have multiple methods with the same input signature, differentiated only by their output signature.
func returnIndexedElement(_ atIndex: Int) -> Int {
return self[atIndex] // Note no explicit casting is necessary, here.
}
func returnIndexedElement(_ atIndex: Int) -> UInt32 {
return self[atIndex]
}
func returnIndexedElement(_ atIndex: Int) -> A {
return self[atIndex]
}
func returnIndexedElement(_ atIndex: Int) -> B {
return self[atIndex]
}
func returnIndexedElement(_ atIndex: Int) -> Float {
return self[atIndex]
}
func returnIndexedElement(_ atIndex: Int) -> String {
return self[atIndex]
}
func returnIndexedElement(_ atIndex: Int) -> [String] {
return self[atIndex]
}
}
let mainObject = C()
// First, let's test the subscripts.
// We have 3 elements, so
let aObject1: A = mainObject[0]
let aObject2: B = mainObject[0]
let aString: String = mainObject[0]
let aPoem: [String] = mainObject[0]
let aInt: Int = mainObject[0]
let aUInt32 = mainObject[0] as UInt32
let aFloat = mainObject[0] as Float
// This will not work. You need to specify the type explicitly when using multiple subscripts, differentiated only by return type.
// let failObject = mainObject[0]
// However, this will work, because the class has only one subscript method defined.
let aObject2_Subscript = aObject2[0]
let aObject2_Poem = aObject2_Subscript.poem
// Next, test the accessor methods.
let bObject1: A = mainObject.returnIndexedElement(1)
let bObject2: B = mainObject.returnIndexedElement(1)
let bString: String = mainObject.returnIndexedElement(1)
let bPoem: [String] = mainObject.returnIndexedElement(1)
let bInt: Int = mainObject.returnIndexedElement(1)
let bUInt32 = mainObject.returnIndexedElement(1) as UInt32
let bFloat = mainObject.returnIndexedElement(1) as Float
// This will not work. You need to specify the type explicitly when using multiple methods, differentiated only by return type.
// let failObject = mainObject.returnIndexedElement(1)