我有几个类看起来像这样:
class A {} class A1 : A {} class A2 : A {} class A3 : A {} class A4 : A {} class main { var a1 : A1 var a2 : A2 var a3s : [A3] var a4s : [A4] func getAll() -> [A] { return ([a1, a2] + a3s + a4s) } }
如果你看看函数getAll(),你会看到我尝试返回一个所有对象的数组,类型是基类A.但是,我总是得到错误:
"二元运算符' +(::)'不能应用于类型的操作数' [Any]'和' [a3s]'"
你知道这种情况下的正确方法吗?
答案 0 :(得分:4)
我想这只是正确地投射数组的问题,你可以解决这个问题:
func getAll() -> [A] {
return ([a1, a2] as [A] + a3s as [A] + a4s)
}
只是为了好玩:如果你想动态地解决它,你可以用这种方式使用反射:
class A {}
class A1 : A {}
class A2 : A {}
class A3 : A {}
class A4 : A {}
class main {
var a1 = A1()
var a2 = A2()
var a3s : [A3] = [A3()]
var a4s : [A4] = [A4(), A4()]
func getAll() -> [A] {
var res = [A]()
Mirror(reflecting:self).children.forEach {
if let a = $0.value as? A {
res.append(a)
} else if let aArray = $0.value as? [A] {
res.append(contentsOf: aArray)
}
}
return res
}
}
let all = main().getAll()
print(all) //A1, A2, A3, A4, A4
答案 1 :(得分:2)
我想这可能是一种更清洁的方式。
BOOL MfcApp::InitInstance()
{
// (...)
CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CMFCPlaygroundDoc),
RUNTIME_CLASS(CMainFrame),
RUNTIME_CLASS(CMFCPlaygroundView)); // <-- derived from CFormView
if (!pDocTemplate)
return FALSE;
AddDocTemplate(pDocTemplate);
// (...)
}
这将创建一个数组数组,然后使用func getAll() -> [A] {
let all: [[A]] = [[a1], [a2], a3s, a4s]
return all.flatMap{$0}
}
将它们展平为一个数组。
答案 2 :(得分:1)
问题是编译器认为您正在尝试添加[Any]
和[A3]
。这是因为[a1, a2] is [Any]
和a3s is [A3]
的类型。但是运营商+
无法做到这一点。
正如其他人所指出的,您可以将语句中的数组转换为[A]
,以便+
运算符可以完成其工作。
由于您提到您有多个类,因此最好创建一个可以重用的函数,并且可以正确地推断出类型。
func merge<T>(_ array: [T]...) -> [T] {
return array.flatMap { $0 }
}
func getAll() -> [A] {
return merge([a1, a2], a3s, a4s)
}