Aşağıdakilerle bu konuyu en basit haline getirmeye çalıştım.
Kurmak
Xcode Sürümü 6.1.1 (6A2008a)
Şu şekilde tanımlanan bir 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
}
}
}
ve numaralandırmayı başka bir dosyada başlatan kod 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")
}
}
Hata
Xcode MyEnum
, ham değer başlatıcısı ile başlatmaya çalışırken bana şu hatayı veriyor :
Cannot convert the expression's type '(rawValue: IntegerLiteralConvertible)' to type 'MyEnum?'
Notlar
Başına Swift Dil Rehberi :
Bir ham değer türü ile bir numaralandırma tanımlarsanız, numaralandırma otomatik olarak ham değerin türünün değerini (çağrılan bir parametre olarak
rawValue
) alan ve bir numaralandırma üyesi veya döndüren bir başlatıcı alırnil
.İçin özel başlatıcı
MyEnum
, numaralandırmanın ham değer başlatıcısının aşağıdaki durum nedeniyle Dil Kılavuzundan kaldırılıp kaldırılmadığını test etmek için bir uzantıda tanımlandı . Ancak aynı hata sonucunu elde eder.Bir değer türü için özel bir başlatıcı tanımlarsanız, artık o tür için varsayılan başlatıcıya (veya bir yapıysa üye başlatıcıya) erişemeyeceğinizi unutmayın. [...]
Özel değer türünüzün varsayılan başlatıcı ve üye başlatıcı ile ve ayrıca kendi özel başlatıcılarınızla başlatılabilir olmasını istiyorsanız, özel başlatıcılarınızı değer türünün orijinal uygulamasının bir parçası yerine bir uzantı olarak yazın.Enum tanımının taşınması,
MyClass.swift
hatayı çözer,bar
ancak için çözmezfoo
.Özel başlatıcıyı kaldırmak her iki hatayı da çözer.
Çözümlerden biri, aşağıdaki işlevi enum tanımına dahil etmek ve sağlanan ham değer başlatıcısı yerine kullanmaktır. Bu nedenle, özel bir başlatıcı eklemenin ham değer başlatıcıyı işaretlemeye benzer bir etkisi varmış gibi görünüyor
private
.init?(raw: Int) { self.init(rawValue: raw) }
Açıkça protokol uygunluğunu beyan
RawRepresentable
içindeMyClass.swift
giderir satır içi hatasıbar
, ancak yinelenen simgeleri hakkında bir bağlayıcı hatası sonuçları (ham-değer türü çeteleler örtülü uygun çünküRawRepresentable
).extension MyEnum: RawRepresentable {}
Burada neler olup bittiğine dair biraz daha bilgi veren var mı? Ham değer başlatıcı neden erişilebilir değil?
internal
kapsamı olmalıdır (veya en azından türle eşleşmelidir), değilprivate
.