Swiftの新しい結果型でジェネリック型を適切に使用するにはどうすればよいですか?

ケニーク

関連する値のResult型が.successジェネリックになるように、Swiftの新しいを使用しようとしています以下のかなり工夫されたサンプルコードは機能しますが、コンパイラが正しい型を推測できるように型キャストを単純化する方法はありTますか?

enum FetchError : Error {
  case unknownKey
}

enum FetchKey {
  case getWidth
  case getName
}

func fetchValue<T>(_ key:FetchKey) -> Result<T, FetchError> {
  switch key {

  case .getName:
    // Ideally I would like to just use: return .success("Johnny Appleseed")
    return Result<String, FetchError>.success("Johnny Appleseed") as! Result<T, FetchError>

  case .getWidth:
    return Result<Double, FetchError>.success(25.0) as! Result<T, FetchError>

  @unknown default:
    return .failure(.unknownKey)
  }
}

// This explicit type declaration is also required.
let r:Result<String, FetchError> = fetchValue(.getName)
print(r)
ロブ・ネピア

型キャストについてのあなたの質問に、あなたは間違いなくそれを単純化することができます:

case .getName:
    return .success("Johnny Appleseed" as! T)

間違ったタイプを要求することがプログラミングエラーと見なされるべきであり(したがってクラッシュするはずである)、結果が外部ソースから得られることは決してない場合、これは問題ありません。データが外部ソースから取得される可能性がある場合は、データが間違っていることに応答してクラッシュすることはありません。

その場合、その種のエラーをモデル化する必要があります。

enum FetchError : Error {
    case unknownKey
    case invalidType
}

次に、(失敗する可能性のある)型変換を行う関数を追加することで、好みに非常に近い構文を作成できます。

func fetchValue<Value>(_ key:FetchKey) -> Result<Value, FetchError> {

    func checkType(_ value: Any) -> Result<Value, FetchError> {
        guard let value = value as? Value else { return .failure(.invalidType) }
        return .success(value)
    }

    switch key {
    case .getName: return checkType("Johnny Appleseed")
    case .getWidth: return checkType(25.0)
    @unknown default: return .failure(.unknownKey)
    }
}

そうは言っても、必要な型注釈の醜さを避けるために、このようにします。

func fetch<Value>(_: Value.Type, forKey key: FetchKey) -> Result<Value, FetchError> { ... }

let r = fetch(String.self, forKey: .getName)

これはのパターンに従いますCodable


いくつかの異なる方法で、ソリューション全体を1か所にまとめました。

結果を返す

enum FetchError : Error {
    case unknownKey
    case invalidType
}

enum FetchKey {
    case width
    case name
}

func fetch<Value>(_: Value.Type, forKey key: FetchKey) -> Result<Value, FetchError> {
    func checkType(_ value: Any) -> Result<Value, FetchError> {
        guard let value = value as? Value else { return .failure(.invalidType) }
        return .success(value)
    }

    switch key {
    case .name: return checkType("Johnny Appleseed")
    case .width: return checkType(25.0)
    @unknown default: return .failure(.unknownKey)
    }
}

スローあり

Resultにラップするよりも、投げた方が少しいいと思います。つまりcheckType、1つの場所に簡単に移動でき、必要な構文に非常に近づくことができます。

func fetch<Value>(_: Value.Type, forKey key: FetchKey) throws -> Value {
    func checkType(value: () throws -> Any) throws -> Value {
        guard let value = try value() as? Value else { throw FetchError.invalidType }
        return value
    }

    return try checkType {
        switch key {
        case .name: return "Johnny Appleseed"
        case .width: return 25.0
        @unknown default: throw FetchError.unknownKey
        }
    }
}

オプション付き

エラーを気にしない場合は、Optionalを使用するとこれが少し簡単になります。

func fetch<Value>(_: Value.Type, forKey key: FetchKey) -> Value? {
    func _fetch() -> Any? {
        switch key {
        case .name: return "Johnny Appleseed"
        case .width: return 25.0
        @unknown default: return nil
        }
    }

    return _fetch() as? Value
}

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

結果の型の文字列値としてジェネリックのクラス名を使用するにはどうすればよいですか

分類Dev

ジェネリックと継承を適切に混合して、望ましい結果を得るにはどうすればよいですか?

分類Dev

値タプルでジェネリック型を使用するにはどうすればよいですか?

分類Dev

デコレータを使用してクラスジェネリック型の実行時型を取得するにはどうすればよいですか?

分類Dev

この関数をジェネリック型にするにはどうすればよいですか?

分類Dev

複数のジェネリック型パラメーターを使用して型を作成するにはどうすればよいですか

分類Dev

ジェネリック型のクラスを取得するにはどうすればよいですか?

分類Dev

Swiftのジェネリック型に型メソッドを追加するにはどうすればよいですか?

分類Dev

GsonのTypeTokenのジェネリック型を配置するにはどうすればよいですか?

分類Dev

Objective-Cのジェネリック型を見つけるにはどうすればよいですか?

分類Dev

このシナリオでジェネリックスと型制約を正しく使用するにはどうすればよいですか?

分類Dev

Tの型を知らずに、ジェネリック型List <T>の「isX」型ガードを作成するにはどうすればよいですか?

分類Dev

実行時にジェネリック型を取得するにはどうすればよいですか?

分類Dev

ジェネリック型SignedNumericをFloatに変換するにはどうすればよいですか?

分類Dev

ジェネリック型に拡張機能を追加するにはどうすればよいですか?

分類Dev

C#のジェネリック関数で型を渡すにはどうすればよいですか?

分類Dev

ジェネリック型パラメーターを使用して関数のベクトルを作成するにはどうすればよいですか?

分類Dev

複合ジェネリック型から値を取得するにはどうすればよいですか?

分類Dev

ジェネリック型を含む配列を宣言するにはどうすればよいですか?

分類Dev

ジェネリックを使用して列挙型の値を取得するにはどうすればよいですか?

分類Dev

Swiftでジェネリック型の引数を取る関数を再割り当てするにはどうすればよいですか?

分類Dev

別のジェネリック基本クラスにC#ジェネリック型制約を追加するにはどうすればよいですか?

分類Dev

valueOfジェネリック列挙型を取得するにはどうすればよいですか?

分類Dev

ジェネリック型とダブルを比較するにはどうすればよいですか

分類Dev

TypeScriptでジェネリック型で型のリストをフィルタリングするにはどうすればよいですか?

分類Dev

ジェネリック型の配列を正しく使用するにはどうすればよいですか?

分類Dev

ジェネリック型への参照がジェネリック型と等しいかどうかを比較できるようにするにはどうすればよいですか?

分類Dev

Simple Injectorを使用してネストされたジェネリック型を登録するにはどうすればよいですか?

分類Dev

ジェネリック型で高次を部分的に適用(またはカレー)するにはどうすればよいですか?

Related 関連記事

  1. 1

    結果の型の文字列値としてジェネリックのクラス名を使用するにはどうすればよいですか

  2. 2

    ジェネリックと継承を適切に混合して、望ましい結果を得るにはどうすればよいですか?

  3. 3

    値タプルでジェネリック型を使用するにはどうすればよいですか?

  4. 4

    デコレータを使用してクラスジェネリック型の実行時型を取得するにはどうすればよいですか?

  5. 5

    この関数をジェネリック型にするにはどうすればよいですか?

  6. 6

    複数のジェネリック型パラメーターを使用して型を作成するにはどうすればよいですか

  7. 7

    ジェネリック型のクラスを取得するにはどうすればよいですか?

  8. 8

    Swiftのジェネリック型に型メソッドを追加するにはどうすればよいですか?

  9. 9

    GsonのTypeTokenのジェネリック型を配置するにはどうすればよいですか?

  10. 10

    Objective-Cのジェネリック型を見つけるにはどうすればよいですか?

  11. 11

    このシナリオでジェネリックスと型制約を正しく使用するにはどうすればよいですか?

  12. 12

    Tの型を知らずに、ジェネリック型List <T>の「isX」型ガードを作成するにはどうすればよいですか?

  13. 13

    実行時にジェネリック型を取得するにはどうすればよいですか?

  14. 14

    ジェネリック型SignedNumericをFloatに変換するにはどうすればよいですか?

  15. 15

    ジェネリック型に拡張機能を追加するにはどうすればよいですか?

  16. 16

    C#のジェネリック関数で型を渡すにはどうすればよいですか?

  17. 17

    ジェネリック型パラメーターを使用して関数のベクトルを作成するにはどうすればよいですか?

  18. 18

    複合ジェネリック型から値を取得するにはどうすればよいですか?

  19. 19

    ジェネリック型を含む配列を宣言するにはどうすればよいですか?

  20. 20

    ジェネリックを使用して列挙型の値を取得するにはどうすればよいですか?

  21. 21

    Swiftでジェネリック型の引数を取る関数を再割り当てするにはどうすればよいですか?

  22. 22

    別のジェネリック基本クラスにC#ジェネリック型制約を追加するにはどうすればよいですか?

  23. 23

    valueOfジェネリック列挙型を取得するにはどうすればよいですか?

  24. 24

    ジェネリック型とダブルを比較するにはどうすればよいですか

  25. 25

    TypeScriptでジェネリック型で型のリストをフィルタリングするにはどうすればよいですか?

  26. 26

    ジェネリック型の配列を正しく使用するにはどうすればよいですか?

  27. 27

    ジェネリック型への参照がジェネリック型と等しいかどうかを比較できるようにするにはどうすればよいですか?

  28. 28

    Simple Injectorを使用してネストされたジェネリック型を登録するにはどうすればよいですか?

  29. 29

    ジェネリック型で高次を部分的に適用(またはカレー)するにはどうすればよいですか?

ホットタグ

アーカイブ