当前位置: 首页 > 面试题库 >

将类型传递给通用Swift扩展,或理想地推断出它

罗毅
2023-03-14
问题内容

说你有

 class Fancy:UIView






    for v:UIView in superview!.subviews
        {
        if let f = v as? Fancy
            { f.hungry = false }
        }

因此,请尝试扩展

public extension UIView
    {
    internal func fancySiblings()->([Fancy])
        {
            return (self.superview!
                .subviews
                .filter { $0 != self }
                .flatMap { $0 as? Fancy }
                )
        }
    }

太好了,您现在可以

    for f:Fancy in self.fancySiblings()
        { f.hungry = false }

太棒了

但,

理想情况下,扩展甚至可以 推断类型 吗?以及采取类型?

所以,类似…

public extension UIView
    {
    internal func siblings<T>( something T )->([T])
        {
            return (self.superview!
                .subviews
                .filter { $0 != self }
                .flatMap { $0 as? T }
                )
        }

然后你可以这样称呼它…

    for f in self.siblings(Fancy)
    for p in self.siblings(Prancy)
    for b in self.siblings(UIButton)

您如何像这样“说明”一个通用扩展名?

看来您可以“向后推断”,

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()

太神奇了,但反过来却行不通。

你甚至可以…

    self.siblings().forEach{
        (f:Fancy) in
        d.hasRingOn = false
        }

因此,我仍然想知道如何“传递”类似的类型,forfinself.siblings(Fancy)并且理想情况下甚至可以推断出它。


问题答案:

只需使用.Type

internal func siblings<T>( something : T.Type)->([T]) {
    ...
}

之后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))

正确输出一个Fancy视图!

为了解决请求的添加,以便有选择地使用显式类型参数或使编译器的类型推断生效。您可以在同一扩展中创建第二个方法

internal func siblings<T>()->([T]) {
    return siblings(T)
}

这样,提供一个显式类型参数将调用方法一,而忽略该方法将需要您使其可推断,并将调用第二个函数,即内部调用第一个函数。

或者 ,您可以使用更 快捷的 方法,并在默认情况下使显式类型参数成为可选参数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 }
        )
}

这将使您可以通过以下方式调用方法

for f in self.siblings(Fancy)

甚至

for f : Fancy in self.siblings()

两者都可以工作,但仍只定义一个功能。



 类似资料:
  • 问题内容: 我正在为核心数据编写通用包装类。 这是我的一些基本类型。没什么特别的。 我已经将我的coredata写在协议中抽象化了。如果您让我知道您对我要提出的抽象的意见,我将不胜感激。但是在扩展中,我遇到了以下错误: 无法将类型“ NSFetchRequest”的值转换为预期的参数类型“ NSFetchRequest <_>” 不确定我该如何解决。我尝试了各种更改代码的尝试,但未成功…… 另外,

  • 假设我有两个公共课,如下所示: 将获取宽度和高度参数的椭圆类。 还有一个Shape类,它应该有任何不同的形式(这就是我扩展它的原因)。 编辑: 我们对GOval、其他类和move()方法了解不够,因此无法给出一个好的答案。 将另一个视为椭圆形类: 问题是,我如何获得在Shape类中的oval中创建的对象oval(

  • 问题内容: 我想为此创建一个扩展名,仅影响… 我了解这些说明是相关的,但不确定如何: 扩展通用类型时,不提供类型参数列表作为扩展定义的一部分。而是在扩展程序的正文中提供原始类型定义的类型参数列表,并且原始类型参数名称用于引用原始定义的类型参数。 基本上,我正在尝试使用此方法: 在没有参数的情况下采取行动…这可能吗? 问题答案: Swift 3.1更新 从Swift 3.1(Xcode 8.3 be

  • 所以我试着做下面这样的事情 并且定义为 当尝试编译代码时,clang给出错误。我发现这是因为你不能从lambda推断出类型。 所以这实际上是正确的,因为我实际上希望的参数类型是从的参数推导出的类型。 所以我的问题是,有没有可能排除参数的推导,而只是使用的推导类型?

  • 问题 你需要向C库函数传递文件名,但是需要确保文件名根据系统期望的文件名编码方式编码过。 解决方案 写一个接受一个文件名为参数的扩展函数,如下这样: static PyObject *py_get_filename(PyObject *self, PyObject *args) { PyObject *bytes; char *filename; Py_ssize_t len; i

  • 我正在尝试按房间类别(手术室或技术室)返回过滤后的