【问题标题】:How to require a generic type implement a generic protocol using a specific type in the protocol如何要求泛型类型使用协议中的特定类型实现泛型协议
【发布时间】:2017-11-03 19:58:30
【问题描述】:

您好,我在当前项目中经常使用泛型。但是,我遇到了一个问题:

我需要一个泛型函数 foo<T> 来获取符合使用特定类型的泛型协议的参数。

例如在 Java 中我可以做到:

public interface Proto<B> {
    public void SomeFunction()
}
public class SampleClass {
}
public class Conforms extends Proto<SampleClass> {
    @Override
    public void SomeFunction () {}
}
public class TestingClass {
    public void Requires (Proto<SampleClass> param) {
        // I can use param
    }
}

如何在 Swift 中执行相同的 Requires() 函数? 我知道在 Swift 中,您在泛型协议中使用 typealias。如何根据typealias 约束参数?

【问题讨论】:

标签: ios generics swift protocols


【解决方案1】:

原型似乎不像 Swift 中的类和结构那样具有泛型,但您可以拥有与 typealias 相关的类型,它们很接近。

您可以使用类型约束来确保您传入的对象采用带有类型约束的Proto。要使您传递给requireProto 具有正确的B,请使用where

Apples documentation on generics 有很多信息。

This blog post 也是一个很好的关于使用泛型做更复杂事情的信息来源。

protocol Proto {
    typealias B
    func someFunction()
}

class SampleClass {}

class Conforms : Proto {
    typealias B = SampleClass
    func someFunction() { }
}

class TestingClass {
    func requires<T: Proto where T.B == SampleClass>(param: T) {
        param.someFunction()
    }
}

【讨论】:

  • 请注意(来自硬敲学院),从 Beta 5 开始,Swift 无法检查关联类型的 where 子句,当您使用实例调用上面的 requires() 时会导致运行时错误比如说“AnotherSampleClass”(报告给 Apple)
【解决方案2】:

您可以使用where 子句为泛型指定多个要求。我认为您的示例可以转换为此,但它会使 Xcode 崩溃。测试版!

protocol Proto {
    func someFunction()
}
class SampleClass {
}
class Conforms: SampleClass, Proto {
    func someFunction() {
    }
}
class TestingClass {
    func requires<T: SampleClass >(param: T) where T: Proto {
        param.someFunction()    // it's this line that kills Xcode
    }
}

let testingClass = TestingClass()
let conforms = Conforms()
testingClass.requires(conforms)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-15
    • 1970-01-01
    • 2014-12-09
    • 1970-01-01
    相关资源
    最近更新 更多