我想创建一个带有NSData
参数的函数,并根据它从NSData
读取的内容返回Array<Int8>
,Array<Int16>
,{ {1}}或Array<Int32>
。
基本上,我需要返回一个Array<Int64>
数组,并在运行时确定特定的子类型。
我被困在函数的签名声明中。 (内部只是一个简单的开关,它将创建特定的数组类型并返回它。)
以下非常基本的测试无法编译
IntegerType
修改
目前似乎不可能,不是因为必须返回协议类型的数组,而是因为IntegerType协议使用class Test {
func test(data:NSData) -> Array<IntegerType> {
return [1, 2, 3]
}
}
。这是一个有趣的相关question
答案 0 :(得分:0)
IntegerType
是一个协议,因此以下内容应该有效:
class Test {
func test(data:NSData) -> Array<T: IntegerType> {
[1, 2, 3]
}
}
答案 1 :(得分:0)
您可以使用enum
with associated values:
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]
...
}
答案 2 :(得分:0)
正如其他人在评论中所说的那样,如果你试图在运行时确定函数的返回类型,这将不起作用。 Swift泛型仅在编译时工作,因此根据NSData中的内容更改返回类型将无法正常工作。
如果你可以在编译时确定返回类型,那么你可以像这样使用generic function声明:
func test<T: IntegerType>(data: NSData) -> Array<T> {
return [1, 2, 3]
}
注意:如果您不以某种方式在函数中明确指定类型,那么您需要定义从函数返回的值所赋予的变量。像这样:
var int8Array: Array<Int8> = test(NSData())
答案 3 :(得分:0)
由于基于通用的解决方案都不起作用,为什么不尝试返回[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!)
}
}
答案 4 :(得分:0)
我解决问题的方法是定义以下协议:
protocol IntegerArrayProtocol {
init(rawData: NSData!, length: Int)
func count() -> Int
subscript(index:Int) -> Int { get }
}
这涉及我需要在阵列上执行的所有操作:
Int
s,无论基础整数如何
输入然后,我创建了一个实现协议的参数化类:
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()
}
}
}
参数类型T
应该能够将自身转换为Int
,并且应该具有zero
值(在初始化数组时使用)。为此,我创建了ConvertibleToInteger
协议,上面用它来限制可能的T
:
protocol ConvertibleToInteger {
class func zero() -> Self
func asInt() -> Int
}
然后,我扩展了我想要创建数组的所有类型:
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
}
}