我的应用程序中有一个简单的类:
class MyClass{
var Name: String
var Foo1: Bar
var Foo2: Bar?
//var Foos: [Bar]
}
Foo1
从不为零,而Foo2
是可选的,因此它可能为零。
与其希望像下面这样的初始化,不如说拥有一个列表属性Foos: [Bar]
,它可能包含1或2个元素。
init(_ Name: String, _ Foo1: Bar, _ Foo2: Bar?){
self.Name = Name
self.Foo1 = Foo1
self.Foo2 = Foo2
}
在C#中,我将编写类似MyClass m = new MyClass("m", New List<Bar>{Bar1, Bar2})
或MyClass m = new MyClass("m", New List<Bar>{Bar1, null})
的文字。我宁愿在MyClass
中将一个属性作为列表,而不是两个单独的字段(其中一个可能为nil)。
我已经尝试过该初始化程序:
init(_ Name: String, _ Foos: [Bar]) {
self.Name = Name
self.Foos = Foos
}
但是当我尝试将匿名列表传递给初始化程序时,出现以下警告:
let m = MyClass("m", [Bar]().append(B1))
不能对不可变值使用变异成员:函数调用返回不可变值
如何像在C#中那样将已填充的匿名列表传递给Swift中的初始化程序?
答案 0 :(得分:1)
尝试此代码
struct Bar { }
class MyClass {
var name: String
var foos: [Bar?]
init(name: String, foos: [Bar?]) {
self.name = name
self.foos = foos
}
}
let bar0 = Bar()
let bar1: Bar? = nil
let object = MyClass(name: "String", foos: [bar0, bar1])
希望您有这个主意。并详细了解它在Swift中的工作方式
答案 1 :(得分:0)
最具挑战性的要求,accepted answer也无法满足:
我不想像下面那样拥有一个初始化,而是希望拥有一个列表属性Foos:[Bar],它可能包含1或2个元素。
一种解决方法可能是自定义运行时错误。
enum BarWrapperError: Error {
case emptyList
}
要传递列表并检查其是否至少包含一个元素,可以引入另一种类型
struct BarWrapper {
init(bars: [Bar]) throws {
guard bars.count > 0 else {
throw BarWrapperError.emptyList
}
self.bars = bars
}
let bars: [Bar]
var firstBar: Bar {
return bars[0]
}
var otherBars:[Bar] {
return Array(bars[1 ..< bars.count])
}
}
BarWrapper
用小节列表初始化。如果此列表为空,将引发错误。
您的MyClass
现在看起来像:
class MyClass {
let name: String
let firstBar: Bar
let otherBars: [Bar]
init(name: String, barWrapper: BarWrapper) {
self.name = name
self.firstBar = barWrapper.firstBar
self.otherBars = barWrapper.otherBars
}
}
如果您关心错误并希望继续执行,可以这样使用
do {
let bar0 = Bar()
let bar1 = Bar()
let barWrapper = try BarWrapper(bars: [bar0, bar1])
let object = MyClass(name: "String", barWrapper: barWrapper)
print(object.otherBars)
} catch BarWrapperError.emptyList {
print("empty bar list")
}
如果您希望在列表为空时使应用程序崩溃,则可以将其缩短为
let bar0 = Bar()
let bar1 = Bar()
let barWrapper = try! BarWrapper(bars: [bar0, bar1])
let object = MyClass(name: "String", barWrapper: barWrapper)
print(object.otherBars)
通过使用try!
您也可以
let bar0 = Bar()
let bar1 = Bar()
if let barWrapper = try? BarWrapper(bars: [bar0, bar1]) {
let object = MyClass(name: "String", barWrapper: barWrapper)
print(object.otherBars)
}
如果您不需要错误处理,并且如果未创建MyClass
实例,则您的应用仍然可以运行。