我有這樣的代碼:
class A{}
class B: A{
var val = 1
}
class C: A{
var num = 5
}
extension Optional where Wrapped == [B?]{
var vals: [B]{
var result = [B]()
if let arr = self{
for part in arr{
if let val = part{
result.append(val)
}
}
}
return result
}
}
extension Optional where Wrapped == [C?]{
var vals: [C]{
var result = [C]()
if let arr = self{
for part in arr{
if let val = part{
result.append(val)
}
}
}
return result
}
}
var one: [B?]? = [B()]
var two: [C?]? = [C(), nil]
print(one.vals.count)
print(two.vals.count)
這是優化的一個:
合二為一,對于B(A的子類)&C(A的子類)
extension Optional where Wrapped: Collection{
var vals: [A]{
var result = [A]()
if let arr = self{
for part in arr{
if let val = part as? A{
result.append(val)
}
}
}
return result
}
}
現在問題來了,
對于以下情況,
如何進行優化?
print(one.vals.first?.val ?? "")
print(two.vals.first?.num ?? "")
我想,我需要一個函式來回傳一個物件的真實型別
PS:我知道,為了處理資料,struct 和協議是完美的
雖然這是一個公司專案,但我是一個新人
uj5u.com熱心網友回復:
您需要引入一個額外的型別變數來說明擴展適用于Optionals where Wrapped.Elementis another Optional of any type。您必須用另一個型別變數來表達“任何型別”部分,但您不能在擴展的宣告中添加此型別變數(盡管正在提議此功能)或屬性的宣告。你可以做的是創建vals一個函式:
func vals<T>() -> [T] where Wrapped.Element == T? {
var result = [T]()
if let arr = self{
for part in arr{
if let val = part{
result.append(val)
}
}
}
return result
}
請注意,這可以簡化為:
extension Optional where Wrapped: Sequence {
func vals<T>() -> [T] where Wrapped.Element == T? {
self?.compactMap { $0 } ?? []
}
}
uj5u.com熱心網友回復:
只是為了好玩。將其保留為計算屬性而不是通用方法的另一種可能方法是創建AnyOptional具有關聯型別的協議Wrapped并遵守Optional它。然后您可以創建一個計算屬性來回傳其Wrapped Element Wrapped型別的陣列:
protocol AnyOptional {
associatedtype Wrapped
var optional: Optional<Wrapped> { get }
}
extension Optional: AnyOptional {
var optional: Optional<Wrapped> { self }
}
extension AnyOptional where Wrapped: Sequence, Wrapped.Element: AnyOptional {
var elements: [Wrapped.Element.Wrapped] {
optional?.compactMap(\.optional) ?? []
}
}
print(one.elements) // "[B]\n"
print(two.elements) // "[C]\n"
print(one.elements.first?.val ?? "") // "1\n"
print(two.elements.first?.num ?? "") // "5\n"
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/368985.html
上一篇:如何在SwiftUI中啟動應用程式時呼叫具有用戶當前位置的API?[復制]
下一篇:SwiftUI中的“.colorName”和“Color.colorName”有什么區別?如果它們相同,為什么會顯示兩個輸出?[復制]
