Swift:返回IntegerType数组的函数
我想创建一个接受NSData参数的函数,并根据从NSData读取的内容返回数组、数组、数组或数组 基本上,我需要返回IntegerType数组,具体的子类型在运行时确定 我被函数的签名声明卡住了。内部只是一个简单的开关,它将创建特定的数组类型并返回它 以下非常基本的测试无法编译Swift:返回IntegerType数组的函数,swift,generics,Swift,Generics,我想创建一个接受NSData参数的函数,并根据从NSData读取的内容返回数组、数组、数组或数组 基本上,我需要返回IntegerType数组,具体的子类型在运行时确定 我被函数的签名声明卡住了。内部只是一个简单的开关,它将创建特定的数组类型并返回它 以下非常基本的测试无法编译 class Test { func test(data:NSData) -> Array<IntegerType> { return [1, 2, 3] } } 编辑 目前
class Test {
func test(data:NSData) -> Array<IntegerType> {
return [1, 2, 3]
}
}
编辑
目前似乎不可能,不是因为必须返回协议类型的数组,而是因为IntegerType协议使用Self。下面是一个有趣的相关IntegerType是一个协议,因此以下内容应该可以工作:
class Test {
func test(data:NSData) -> Array<T: IntegerType> {
[1, 2, 3]
}
}
您可以使用:
enum IntArray {
case Int8([Swift.Int8])
case Int16([Swift.Int16])
case Int32([Swift.Int32])
case Int64([Swift.Int64])
}
class Test {
func test(data:NSData) -> IntArray {
return IntArray.Int8([1, 2, 3]);
}
}
在用户端:
let obj = Test()
let array = obj.test(dat)
switch array {
case .Int8(let ary):
// here, ary is [Int8]
...
case .Int16(let ary):
// here, ary is [Int16]
...
case .Int32(let ary):
// here, ary is [Int32]
...
case .Int64(let ary):
// here, ary is [Int64]
...
}
正如其他人在评论中所说的,如果您试图在运行时确定函数的返回类型,那么这将不起作用。Swift泛型只在编译时工作,因此根据NSData中的内容更改返回类型将不起作用 如果可以在编译时确定返回类型,则可以使用如下声明:
func test<T: IntegerType>(data: NSData) -> Array<T> {
return [1, 2, 3]
}
注意:如果您没有以某种方式在函数中显式指定类型,那么您需要定义从函数返回的值分配给的变量。像这样:
var int8Array: Array<Int8> = test(NSData())
既然所有基于泛型的解决方案都不起作用,为什么不尝试返回[Any]并按如下方式检查返回类型:-
func test(data:NSData) -> [Any]
{
var value1:Int8 = 1
var value2:Int8 = 2
return [value1,value2]
}
var x = test(NSData())
for xin in x
{
var intxin = xin as? Int8
if intxin != nil
{
println(intxin!)
}
}
我解决问题的方法是定义以下协议:
protocol IntegerArrayProtocol {
init(rawData: NSData!, length: Int)
func count() -> Int
subscript(index:Int) -> Int { get }
}
final class IntegerArray<T: ConvertibleToInteger>: IntegerArrayProtocol {
let arr: [T]
init(rawData: NSData!, length: Int){
//create array and allocate memory for all elements
arr = Array<T>(count: length, repeatedValue: T.zero())
// read it from the NSData source
// ....
}
func count() -> Int{
return arr.count
}
subscript(index:Int) -> Int {
get {
return arr[index].asInt()
}
}
}
这将处理我需要在阵列上执行的所有操作:
从原始内存中读取它
数一数它有多少元素
通过索引访问其元素,始终返回整数,而不考虑基础整数
类型
然后,我创建了一个实现协议的参数化类:
protocol IntegerArrayProtocol {
init(rawData: NSData!, length: Int)
func count() -> Int
subscript(index:Int) -> Int { get }
}
final class IntegerArray<T: ConvertibleToInteger>: IntegerArrayProtocol {
let arr: [T]
init(rawData: NSData!, length: Int){
//create array and allocate memory for all elements
arr = Array<T>(count: length, repeatedValue: T.zero())
// read it from the NSData source
// ....
}
func count() -> Int{
return arr.count
}
subscript(index:Int) -> Int {
get {
return arr[index].asInt()
}
}
}
然后,我扩展了要创建数组的每种类型:
extension Int8: ConvertibleToInteger{
static func zero() -> Int8{
return 0
}
func asInt() -> Int{
return Int(self)
}
}
extension Int16: ConvertibleToInteger{
static func zero() -> Int16{
return 0
}
func asInt() -> Int{
return Int(self)
}
}
extension Int32: ConvertibleToInteger{
static func zero() -> Int32{
return 0
}
func asInt() -> Int{
return Int(self)
}
}
extension Int64: ConvertibleToInteger{
static func zero() -> Int64{
return 0
}
func asInt() -> Int{
return Int(self)
}
}
最后,为了从NSData读取数组,我创建了以下函数:
func readArray(rawData: NSData, length: Int): IntegerArrayProtocol? {
qBytes = // read from NSData how many bytes each element is
switch(qBytes){
case 1:
return IntegerArray<Int8>(rawData: rawData, length: length)
case 2:
return IntegerArray<Int16>(rawData: rawData, length: length)
case 3 ... 4:
return IntegerArray<Int32>(rawData: rawData, length: length)
case 5 ... 8:
return IntegerArray<Int64>(rawData: rawData, length: length)
default:
return nil
}
}
是的,它给了我一个“0”没有成员“Element”错误您使用的是哪个版本的Swift?它使用Xcode->About Xcode Version 6.0.1 for iOSOh报告的版本6.1 6A1030为我编译。我现在看到,您在最初发布后就编辑了代码——我上面提供的函数签名有效,但尝试从函数返回值确实会产生上面识别的错误Rajeev Bhatia。我想得越多,就越不相信您所尝试的是可能的:定义一个返回值为泛型的函数,其实际类型由函数的实现决定,而不是由其输入参数的类型决定。我想不出一个现有的例子。你能吗?我想弄明白他为什么要这么做,尤其是对Int,因为苹果明确主张使用通用Int类型而不是特定类型。你为什么要这样做?苹果官方文档本身要求您对任何整数大小使用Int一致使用Int有助于代码互操作性,避免在不同的数字类型之间转换,并匹配整数类型推断基本上,我需要返回IntegerType数组,在运行时确定特定的子类型。-不可能。推断类型将在编译时确定。基本方法应该始终是泛型的,或者尽可能使用Int作为通用类型。在泛型数组中,T表示占位符类型名称。当一个类型(比如数组)将被实例化时,T必须替换为一个类型。IntegerType不是类型,它是协议。@Eduardo您假设泛型函数参数和泛型返回值之间不存在并行性。请考虑一下:如何声明一个变量来存储函数的返回值?必须在编译时知道类型以分配存储,但在运行时之前无法知道返回值的实际类型。在编译时,您只知道它符合IntegerType协议。问题是,我以后对IntArray做不了什么。我需要一个能让我以一种通用的方式操作数组的东西。是的,我知道。但是,即使你可以像数组一样,你怎么能提取它的值呢?迟早,您必须进行类型转换并将其转换为最终的混凝土类型。此外,对于{switch{…}}循环中的每个for元素,都必须这样做,因为数组可能类似于[Int8,Int32,Int16,Int16,…]。我认为这不是一个好主意。我想要避免的是在声明中显式,因为实际类型将在运行时根据我从NSData@Eduardo这应该可以很好地工作,我的注意是,只有在您没有通过查看案例中的NSData来定义函数本身的类型的情况下。我基本上把它放在那里,以防你把我的答案抄到操场上
爱德华多:事实上,我收回这句话。如果Swift编译器不知道函数在编译时将返回什么,那么这将不起作用。