Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/114.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios Swift通用函数错误?_Ios_Xcode_Swift - Fatal编程技术网

Ios Swift通用函数错误?

Ios Swift通用函数错误?,ios,xcode,swift,Ios,Xcode,Swift,这是我的密码: func swapTwoValues<T>(inout a: T, inout b: T){ let temp = a a = b b = temp } var aInt = 5 var bInt = 98 swapTwoValues(&aInt, &bInt) func swaptwo值(inout a:T,inout b:T){ 设温度=a a=b b=温度 } var aInt=5 var bInt=98 swaptwo值(&aIn

这是我的密码:

func swapTwoValues<T>(inout a: T, inout b: T){
  let temp = a
  a = b
  b = temp
}
var aInt = 5
var bInt = 98
swapTwoValues(&aInt, &bInt)
func swaptwo值(inout a:T,inout b:T){
设温度=a
a=b
b=温度
}
var aInt=5
var bInt=98
swaptwo值(&aInt,&bInt)
调用函数swaptwavalues()时,“T”为Int类型

但是当我把代码改成

func swapTwoValues<T,S:String>(inout a: T, inout b: T , inout c: S ){
  let temp = a
  a = b
  b = temp
  c = "Hi"
}
var aInt  = 5
var bInt  = 98
var cStr  = "Hello"
swapTwoValues(&aInt, &bInt,&cStr)
func swaptwo值(输入输出a:T、输入输出b:T、输入输出c:S){
设温度=a
a=b
b=温度
c=“你好”
}
var aInt=5
var bInt=98
var cStr=“你好”
交换值(&aInt、&bInt和cStr)
这将显示错误,但为什么

我将“S”设置为字符串类型,这似乎是正确的

代码
不应该工作,原因很简单,字符串是一个结构,并且不能扩展结构。所以S实际上是一个无效类型

如果你想让
c
成为一个枚举,你应该使用

如果您正在考虑向字符串类型添加功能,则应将
c
设置为普通字符串,然后使用字符串扩展来实现该功能

如果您确实希望将字符串扩展为对象,则应改为扩展NSString

例如:

class MyString: NSString {
  // My code
}
然后你的泛型变成:
,这是完全有效的


扩展NSString的缺点是类型现在是引用类型,但是这只是Swift的一部分,您不能扩展(就继承而言)结构。

这不起作用的原因是
a:B
语法要求泛型占位符表示符合协议或从基类继承的任何类型。由于
String
是一个结构,而不是一个协议或类,因此会出现一个错误(“从非协议继承,非类类型'String'))。如果尝试像
Optional
这样的枚举,也会出现同样的错误

为什么会这样?泛型的目的是允许您为多个可能的类型编写代码,然后让Swift在编译时允许将该函数应用于满足该要求的多个不同类型

结构不允许继承(只有类允许)。所以当你说
func f(c:S)时
您将定义一个通用占位符
S
,该占位符只能表示一种类型的
String
,而不能表示其他类型。这将是毫无意义的–您还可以将
String
指定为非通用参数,即
func f(S:String)
,因为它不可能是其他类型

另一方面,类确实允许继承,因此如果您有一个类
MyClass
,您可以编写
func f:(c:S)
,因为在编译时,您可以传入
MyInheritedClass
,一个从
MyClass
继承的类

但结构可以符合协议。因此,例如,假设您想要编写仅当一个值大于另一个值时才交换值的内容:

func swapIfGreater<T: Comparable>(inout a: T, inout b: T) {
    // this is allowed because conformance to the the 
    // Comparable protocol guarantees > is available
    if a > b {
        // avoid temporaries with this one weird trick :)
        (a, b) = (b, a)
    }
}

// i and j are Ints (a kind of struct)
var i = 40, j = 30
swapIfGreater(&i, &j)

// s1 and s2 are Strings
var s1 = "zebra", s2 = "aardvark"
swapIfGreater(&s1, &s2)

// Bool doesn’t support the Comparable protocol
// (false is not “less than” or “greater than” true)
// so this won’t compile:
var b1 = true, b2 = false
swapIfGreater(&b1, &b2)

为什么不能扩展结构?教程说“扩展为现有的类、结构或枚举类型添加新功能”。很抱歉,这是一个错误的用词。可以使用“扩展”来扩展结构。但不能通过继承来“扩展”。区别在于“扩展”有特殊的限制(例如,它们不能存储新的成员变量,这将增加类型的大小)f f导入基础,字符串隐式转换NString。因为NSString是一个类,我想知道S:String是否在这种情况下抛出错误。
// It’s as if Swift writes two versions of swapIfGreater for you automatically:
func swapIfGreater(inout a: Int, inout b: Int) {
    if a > b {
        (a, b) = (b, a)
    }
}

func swapIfGreater(inout a: String, inout b: String) {
    if a > b {
        (a, b) = (b, a)
    }
}