Позвольте мне начать с того, что у меня есть работы ...
let a:String
let b:Int
let c:Double
init?(doc:XMLDocument){
guard let tempString = (try? doc.objects(forXQuery: "path/path/A").first as? XMLNode)?.stringValue else {return nil}
self.a = tempString
guard let tempString2 = (try? doc.objects(forXQuery: "path/B").first as? XMLNode)?.stringValue else {return nil}
guard let tempInt = Int(tempString2) else {return nil}
self.b = tempInt
guard let tempString3 = (try? doc.objects(forXQuery: "path/path/C").first as? XMLNode)?.stringValue else {return nil}
guard let tempDouble = Double(tempString3) else {return nil}
self.c = tempDouble
}
}
Я не доволен этим. Я могу упростить, выполнив нулевую проверку и повторно используя временную переменную
init?(doc:XMLDocument){
var tempString:String? = (try? doc.objects(forXQuery: "path/path/A").first as? XMLNode)?.stringValue
if tempString != nil {self.a = tempString!} else {return nil}
tempString = (try? doc.objects(forXQuery: "path/B").first as? XMLNode)?.stringValue
if tempString != nil && Int(tempString!) != nil {self.b = Int(tempString!)!} else {return nil}
tempString = (try? doc.objects(forXQuery: "path/path/C").first as? XMLNode)?.stringValue
if tempString != nil && Double(tempString!) != nil {self.c = Double(tempString!)!} else {return nil}
}
В идеале я хочу иметь возможность назначать свойства, поскольку я проверяю их, не проходя какую-то временную переменную.
что-то вроде:
struct Foo {
let a:String
let b:Int
let c:Double
init?(doc:XMLDocument){
do {
if case a = try (doc.objects(forXQuery: "path/path/A").first as? XMLNode)?.stringValue { } else {return nil}
if case b = Int(try (doc.objects(forXQuery: "path/path/B").first as? XMLNode)?.stringValue ?? "ZZZ") { } else {return nil}
if case c = Double(try (doc.objects(forXQuery: "path/path/C").first as? XMLNode)?.stringValue ?? "ZZZ") { } else {return nil}
} catch {
return nil
}
}
}
Это ошибки с использованием self без инициализации всех сохраненных свойств.
Есть ли лучший способ сделать это?