2015-01-31 26 views
1

在Swift中,我声明了一个函数,它与Array.count的区别仅在于,如果array == nil函数返回0。这与我的UITableViewDataSource有关,但这并不重要。问题是,如果我声明功能:传递包含类或结构的数组

class func countOfItemsInArray(array: [AnyObject]?) -> Int 

,然后尝试将它传递结构的数组,它宣称在数组中的结构不符合AnyObject。我明白为什么这是(我认为),但是有没有办法使这个工作类 structs,或者我应该放弃复制和粘贴?

回答

0

如果使用Any代替AnyObject你可以通过任何类型的,所以还结构:

class func countOfItemsInArray(array: [Any]?) -> Int 

这是一种奇怪的。

我用这个功能:

func countOfItemsInArray(array: [Any]?) -> Int { 
    return array != nil ? array!.count : 0 
} 

宣告你的两个Assignment结构,并把它们放入数组:

let structOne = Assignment(name: "1", dueDate: NSDate(), subject: "1") 
let structTwo = Assignment(name: "2", dueDate: NSDate(), subject: "2") 
let myArray: [Assignment] = [structOne, structTwo] 

但这里有一个有趣的部分。
当调用println(countOfItemsInArray(myArray))它给人的错误:

<stdin>:27:33: error: 'Assignment' is not identical to 'Any' 
println(countOfItemsInArray(myArray)) 
^ 
<stdin>:17:26: note: in initialization of parameter 'array' 
func countOfItemsInArray(array: [Any]?) -> Int { 
^ 

所以我测试,如果myArray[Any]类型:

println(myArray is [Any]) 

到SWIFT说:

<stdin>:25:17: error: 'Any' is not a subtype of 'Assignment' 
println(myArray is [Any]) 
^ 

但是当我改变myArray[Any]型号注释:

let myArray: [Any] = [structOne, structTwo] 

当简单地交给字面到它的工作原理的功能,太:

countOfItemsInArray([structOne, structTwo]) 

整个代码示例可以看出here

+0

我得到一个错误,“‘myStructType’不等同于‘任何’” – PopKernel 2015-01-31 18:43:18

+0

你能张贴代码(或链接到它)? – 2015-01-31 18:44:59

+0

当然。功能在这里:http://pastebin.com/cztjMbFW – PopKernel 2015-01-31 18:49:12

3

泛型可能更适合这个问题,而不是依赖于[AnyObject]的协方差。即在nil情况下,一个可选的阵列上工作并返回0的countElements一个版本可能是这样的:

func countElements<T>(array: [T]?) -> Int { 
    return array?.count ?? 0 
} 

当你调用countElements与任何类型的数组,占位符T被替换为元素的类型包含在数组中。

请注意,此版本将现有的countElements重载为采用可选的版本。如果你使用非可选或任何其他类型的集合调用它,Swift版本将被调用,如果你传入一个可选数组,那么将会调用这个。这是一个很好的做法(我认为很好)或不好的做法(有些人可能会拒绝:)是有争议的。

上任何集合类型的作品一个版本是:

func countElements<C: CollectionType>(col: C?) -> C.Index.Distance { 
    return col.map { countElements($0) } ?? 0 
} 
+0

你的解决方案与泛型是完美的。不过,我会避免重写Swift标准函数。更具体地说,我承认我不知道Cocoa(以及其他操作系统库/框架)是否可以看到您的countElements版本。如果可能的话,也许重写方法有点不安全。 – 2015-01-31 19:40:25

+0

Cocoa没有任何风险(即使它是一种可能性,我怀疑它不是)调用此版本,因为Swift版本在重载解析优先级中超前(即使Swift会隐式地将非可选项上转换为可选项,要求在啄食顺序中似乎降低的呼叫)。我不会主张以现有的调用方式导致模糊的方式重载现有的函数(尽管我猜你可以在不知情的情况下做到这一点)。 – 2015-01-31 19:44:11

+0

好的在你的声明中你没有使用“public”访问控制修饰符。因此,您的** countElements **版本仅在声明它的项目内部可见。那么它不应该干涉其他图书馆。 – 2015-01-31 19:47:07

相关问题