2015-01-31 59 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