无法将任何数组类型传递给以[Any]为参数的函数

时间:2015-07-29 09:56:19

标签: arrays swift

我有一个[String]

类型的数组
let names = ["Joffrey", "Cersei", "Mountain", "Hound"]

我有一个函数,它采用[Any]类型的数组。

func printItems(items: [Any]){
    for item in items {
        print(item)
    }
}

现在当我用names作为参数调用函数时,

printItems(names)

我收到错误无法使用类型为'([String])'的参数列表调用'printItems'。

Any只是所有类型隐含符合的协议的typealias

思想?

3 个答案:

答案 0 :(得分:2)

这是Swift的一个令人惊讶的限制。您无法转换数组以键入function string_shift(&$str){ $first_char = substr($str, 0, 1); $str = substr($str, 1); return $first_char; } ,因此您无法将其传递给类型为[Any]的函数。您可以使用[Any]来投射数组的每个项目:

map

但是,在Swift中执行此操作的正确方法是使用Generics

printItems(names.map {$0 as Any})

答案 1 :(得分:1)

虽然每个类型都符合Collections.sort( ... ),但这与所有类型继承的通用隐式超类不同。

将类型转换为协议时,将创建具有不同结构的新值。因此,对于类型为Any的字符串,需要从Any表示进行物理转换:

String

sizeof(String) // 24 bytes (on 64-bit, anyway) 表示:

Any

由于值类型直接保存在数组中,因此数组将是一个非常不同的形状,因此编译器必须完成相同的操作:

sizeof(Any) // 32 bytes, includes some meta data 
            // about what the type really is

Swift可能会为你自动化这个过程(如果你将一个变量传递给一个带names.map { $0 as Any } // create a new array, with the Any versions 的函数)。但我个人很高兴它没有,我宁愿这更明确 - 假设你的数组是巨大的,这将是隐含在幕后的很多处理。

这与你有一个引用类型数组不同,它们都是指向实际数据的指针,因此大小相同,并且在向上转换时不需要转换:

Any

所以说“这个class C { } class D: C { } let d = D() let c: C = d unsafeBitCast(d, UnsafePointer<Void>.self) // these value will unsafeBitCast(c, UnsafePointer<Void>.self) // be the same 数组实际上是一个[D]数组”只是编译器同意这些类型可以替换的问题,不需要进行数据转换:

[C]

但是当与类一起使用时,协议仍然与超类引用不同:

// so this works fine, 
// no runtime transformation needed:
func f(cs: [C]) { }
let ds = [D(),D()]
f(ds)

答案 2 :(得分:0)

你需要明确地输入你的let声明 声明一个Any数组,而不是一个特定的类型数组。

使用您当前的声明,Swift会将其评估为[String]数组。 而不是[Any]数组。

要解决您的问题,请执行以下操作:

foo = fmap DTL.last $ DTLIO.readFile "../../../../etymwn.tsv

如果要保留let声明,请使用AnyObject 在你的printItems函数中,它将被Swift接受。

let names : [Any] = ["Joffrey", "Cersei", "Mountain", "Hound"]