2017-07-16 26 views
-1

我有以下枚舉:用於類型轉換關聯類型的guard case的單個表達式?

enum JSONData { 
    case dict([String:Any]) 
    case array([Any]) 
} 

我想這樣做使用後衛的情況下,讓有型鑄造匹配分配模式。我不僅要確保someData.array,而且它的關聯類型是[Int]而不僅僅是[Any]。這是可能的一個單一的表達?類似如下:

let someData: JSONData = someJSONData() 
guard case let .array(anArray as [Int]) = someData 
else { return } 

但上述不編譯;錯誤是downcast pattern value of type '[Int]' cannot be used。我知道這是可能的以下,但我寧願做一個單一的表達如果可能的話。

guard case let .array(_anArray) = someData, let anArray = _anArray as? [Int] 
else { return } 
+0

我想說'case .array(let x as [Int])''但我不在電腦附近! –

+0

不,同樣的錯誤 – BallpointBen

+0

如果它是一個switch語句,我認爲你可以使用where子句'case .array(let x),其中x是[Int]',可能還有防範。 –

回答

0

由於Swift的模式匹配實現中的限制,您要做的事情是不可能的。它實際上叫了here

// FIXME:目前,我們不容許「ISA」模式,
//需要有趣的條件向下轉換子模式。

This answer試圖解釋爲什麼,雖然不足。但是,如果您不使用泛型作爲關聯值,它們確實會指向一個有趣的信息片斷,從而使這些信息起作用。

下面的代碼實現了一個襯墊,但失去了一些其他的功能:

enum JSONData { 
    case dict(Any) 
    case array(Any) 
} 

let someData: JSONData = JSONData.array([1]) 

func test() { 
    guard case .array(let anArray as [Int]) = someData else { 
     return 
    } 

    print(anArray) 
} 

可替換地,相同的一個襯裏可通過在枚舉定義效用函數來實現該注塑基礎值到Any 。這條路線保留了案例和相關值的類型之間的良好關係。

enum JSONData { 
    case dict([String : Any]) 
    case array(Array<Any>) 

    func value() -> Any { 
     switch self { 
     case .dict(let x): 
      return x 
     case .array(let x): 
      return x 
     } 
    } 
} 

// This coercion only works if the case is .array with a type of Int 
guard let array = someData.value() as? [Int] else { 
    return false 
} 
相關問題