Swift 将类型传递给函数以返回返回该类型的闭包?
我一直在研究Exercism.io的Swift track,在将我针对BinarySearchTree问题的解决方案重构为小型代码后,我注意到一个似乎可以重构的模式。我想答案是“不,你不能那样做”,但我觉得这是值得问的Swift 将类型传递给函数以返回返回该类型的闭包?,swift,types,Swift,Types,我一直在研究Exercism.io的Swift track,在将我针对BinarySearchTree问题的解决方案重构为小型代码后,我注意到一个似乎可以重构的模式。我想答案是“不,你不能那样做”,但我觉得这是值得问的 typealias BinarySearchTree = BST indirect enum BST< T: Comparable> { case N( T, BST, BST ) case E init( _ v: T ) { self
typealias BinarySearchTree = BST
indirect enum BST< T: Comparable> {
case N( T, BST, BST )
case E
init( _ v: T ) { self = .N( v, .E, .E ) }
mutating func insert( _ n: T ) {
if case .N( let v, var l, var r ) = self {
if n <= v { l.insert( n ) } else { r.insert( n ) }
self = .N( v, l, r )
} else { self = .N( n, .E, .E ) }
}
var data: T? { if case let .N( v, _, _ ) = self { return v } else { return nil } }
var left: BST? { if case let .N( _, l, _ ) = self { return l } else { return nil } }
var right: BST? { if case let .N( _, _, r ) = self { return r } else { return nil } }
func allData() -> [ T ] { if case let .N( v, l, r ) = self { return l.allData() + [ v ] as [ T ] + r.allData() } else { return [ T ]() } }
}
这完全可以通过一个助手函数来简化,而且可能应该简化:
private var vlr: (T, BST, BST)? {
switch self {
case let .N(v, l, r): return (v,l,r)
case .E: return nil
}
}
var data: T? { return vlr?.0 }
var left: BST? { return vlr?.1 }
var right: BST? { return vlr?.2 }
我在枚举上构建了这些类型的帮助器,以便始终将相关数据转换为可选数据(在某些情况下,作为公共方法)
这也可以用于allData
,我可能会这样写(chained+
因在Swift中产生编译问题而臭名昭著,并且由于创建中间副本,运行时效率极低):
令人惊叹的!我想这是一个太接近问题的例子。我看不到过去的类型,意识到我可以将它们全部返回,然后从一个元组中选择我需要的。谢谢我讨厌看到重复的代码可以像你展示的那样封装。在
allData()
中链接的+
上,我知道您提到的性能问题。我想这就是为什么我需要将[value]转换为[T]
,它才能工作的原因。我有一个稍微不那么简洁的版本,在一次迭代中使用了.append()
,直到我把它转换成链接的+
版本。是的,我不知道为什么+
需要as[t]
。这是所有疯狂的+
重载的奇怪副作用。
private var vlr: (T, BST, BST)? {
switch self {
case let .N(v, l, r): return (v,l,r)
case .E: return nil
}
}
var data: T? { return vlr?.0 }
var left: BST? { return vlr?.1 }
var right: BST? { return vlr?.2 }
func allData() -> [ T ] {
if let (v, l, r) = vlr {
var result = l.allData()
result.append(v)
result.append(contentsOf: r.allData())
return result
}
return []
}