1. ホーム
  2. swift

[解決済み] カスタムイニシャライザを持つSwift enumはrawValueイニシャライザを失う

2022-12-28 13:04:37

質問

私はこの問題を最も単純な形に煮詰めるために、次のようにしました。

セットアップ

Xcode バージョン 6.1.1 (6A2008a)

で定義されたenumは MyEnum.swift :

internal enum MyEnum: Int {
    case Zero = 0, One, Two
}

extension MyEnum {
    init?(string: String) {
        switch string.lowercaseString {
        case "zero": self = .Zero
        case "one": self = .One
        case "two": self = .Two
        default: return nil
        }
    }
}

と、別のファイルでenumを初期化するコード。 MyClass.swift :

internal class MyClass {
    let foo = MyEnum(rawValue: 0)  // Error
    let fooStr = MyEnum(string: "zero")

    func testFunc() {
        let bar = MyEnum(rawValue: 1)  // Error
        let barStr = MyEnum(string: "one")
    }
}

エラー

を初期化しようとすると、Xcodeは次のようなエラーを出します。 MyEnum をその生の値のイニシャライザーで初期化しようとすると、次のようなエラーが発生します。

Cannot convert the expression's type '(rawValue: IntegerLiteralConvertible)' to type 'MyEnum?'

注意事項

  1. 1 つにつき Swift言語ガイド :

    生の値の型を持つ列挙型を定義すると、列挙型は自動的に生の値の型の値を取るイニシャライザーを受け取ります (このパラメータは rawValue というパラメータ) を取り、列挙型のメンバまたは nil .

  2. のカスタムイニシャライザは MyEnum は、以下のようなケースから、enum の raw-value イニシャライザが削除されているかどうかをテストするために拡張モジュールで定義されました。 言語ガイドの . しかし、それは同じエラーの結果を達成します。

    値型にカスタムイニシャライザを定義すると、その型のデフォルトイニシャライザ(構造体の場合はメンバイニシャライザ)にはアクセスできなくなることに注意してください。[...]

    デフォルトのイニシャライザーとメンバ単位のイニシャライザー、および独自のイニシャライザーで初期化できるようにしたい場合は、値型の元の実装の一部としてではなく、拡張機能でカスタムのイニシャライザーを記述してください。

  3. enumの定義を MyClass.swift のエラーは解決されます。 bar に対するエラーは解決されますが foo .

  4. カスタムイニシャライザーを削除すると、両方のエラーが解決されます。

  5. 1 つの回避策は、enum の定義に次の関数を含め、提供された raw-value のイニシャライザの代わりにそれを使用することです。つまり、カスタムのイニシャライザーを追加すると、生の値のイニシャライザーをマークするのと同様の効果があるように思えます。 private .

    init?(raw: Int) {
        self.init(rawValue: raw)
    }
    
    
  6. プロトコルの適合性を明示的に宣言し RawRepresentableMyClass.swift のインラインエラーは解決されます。 bar を解決しますが、重複シンボルに関するリンカーエラーが発生します (生の値型の列挙は暗黙のうちに RawRepresentable ).

    extension MyEnum: RawRepresentable {}
    
    

ここで何が起こっているのか、誰かもう少し洞察を与えてくれませんか?なぜraw-valueイニシャライザーはアクセスできないのでしょうか?

どのように解決するのですか?

このバグは、Xcode 7とSwift 2で解決されます。