Fat*_*tie 20 generics functional-programming ios swift swift-extensions
说你有
class Fancy:UIView
Run Code Online (Sandbox Code Playgroud)
你想找到所有兄弟姐妹的Fancy意见. 没问题 ......
for v:UIView in superview!.subviews
{
if let f = v as? Fancy
{ f.hungry = false }
}
Run Code Online (Sandbox Code Playgroud)
所以,尝试扩展,
public extension UIView
{
internal func fancySiblings()->([Fancy])
{
return (self.superview!
.subviews
.filter { $0 != self }
.flatMap { $0 as? Fancy }
)
}
}
Run Code Online (Sandbox Code Playgroud)
太棒了,你现在可以
for f:Fancy in self.fancySiblings()
{ f.hungry = false }
Run Code Online (Sandbox Code Playgroud)
太棒了.
但,
所以,像......
public extension UIView
{
internal func siblings<T>( something T )->([T])
{
return (self.superview!
.subviews
.filter { $0 != self }
.flatMap { $0 as? T }
)
}
Run Code Online (Sandbox Code Playgroud)
然后你可以称之为......
for f in self.siblings(Fancy)
for p in self.siblings(Prancy)
for b in self.siblings(UIButton)
Run Code Online (Sandbox Code Playgroud)
你怎么能"告诉"一个通用扩展使用的类型,比如??
看来你可以"向后推断",
public extension UIView
{
internal func incredible<T>()->([T])
{
return (self.superview!
.subviews
.filter { $0 != self }
.flatMap { $0 as? T }
)
}
for f:Fancy in self.incredible()
for p:Prancy in self.incredible()
Run Code Online (Sandbox Code Playgroud)
这是惊人的,但不是相反的方式.
你甚至可以......
self.siblings().forEach{
(f:Fancy) in
d.hasRingOn = false
}
Run Code Online (Sandbox Code Playgroud)
所以我仍然想知道如何"传入"类似的东西for f in self.siblings(Fancy),理想情况下,甚至推断它.
luk*_*302 19
只需使用.Type:
internal func siblings<T>( something : T.Type)->([T]) {
...
}
Run Code Online (Sandbox Code Playgroud)
之后for f in self.siblings(Fancy)应该完全按预期工作.
完整的工作示例:
class Fancy : UIView {}
public extension UIView {
internal func siblings<T>( _ : T.Type)->([T]) {
return (self.superview!
.subviews
.filter { $0 != self }
.flatMap { $0 as? T }
)
}
}
let superView = UIView()
let view = UIView()
superView.addSubview(view)
superView.addSubview(UIView())
superView.addSubview(Fancy())
print(view.siblings(Fancy))
Run Code Online (Sandbox Code Playgroud)
正确输出一个Fancy视图!
要解决所请求的添加,以便可选地使用显式类型参数或生成编译器的类型推断.您可以在同一扩展中创建第二个方法
internal func siblings<T>()->([T]) {
return siblings(T)
}
Run Code Online (Sandbox Code Playgroud)
这样提供一个显式类型参数调用方法一,省略它将要求你使它成为可推断的并将调用第二个函数,在内部调用第一个函数.
或者,您可以使用更加流畅的方式,并使显式类型参数成为可选的默认值nil.显然,这将在省略类型参数的情况下强制推断:
// power extension, it provides both infered or stated typing
internal func siblings<T>(_ : T.Type? = nil) -> ([T]) {
return (self.superview!
.subviews
.filter { $0 != self }
.flatMap { $0 as? T }
)
}
Run Code Online (Sandbox Code Playgroud)
这将使您能够通过调用方法
for f in self.siblings(Fancy)
Run Code Online (Sandbox Code Playgroud)
甚至
for f : Fancy in self.siblings()
Run Code Online (Sandbox Code Playgroud)
两者都可以工作,但仍然只定义一个功能.