return 具有关联类型的协议

return protocol with associated type

如何return协议与关联类型?

protocol AProtocol {

}

class A: AProtocol {

}

class Main {
    func sendA() -> AProtocol {
        return A()
    }
}

有效。

但是

protocol BProtocol {
    associatedtype B
}

class B: BProtocol {
    typealias B = Int
}

class Main {
    func sendA() -> AProtocol {
        return A()
    }

    func sendB() -> BProtocol { // error
        return B()
    }

// function1
    func sendB_<T: BProtocol>() -> T{
        return B() as! T
    }
}

我想在功能 1 中 return 'return B()' 可能吗?

您正在尝试 return BProtocol 情况 1。问题是 PAT(关联类型协议)不完全是 类型。它们充当类型的占位符。所以你不能直接return BProtocol

Swift 5.1

我不是 100% 确定,但我认为在 swift (5.1) 的下一次迭代中,他们引入了 不透明类型 ,它允许您想要的功能。

在这种情况下,您可以这样称呼它:

func sendB() -> some BProtocol { 
    return B()
}

在这个函数中

func sendB_<T: BProtocol>() -> T{
    return B() as! T
}

你不能 return 一个 B 作为一个 T 因为使用该函数的人定义了 T 是什么,而不是你和 T 可以是符合 Protocol 的任何类型 例如,我可以这样做:

class C: BProtocol 
{
    typealias B = Float
}

let c: C = Main().sendB_()

通过这样做,我将 T 设置为 CsendB_() 中的强制类型转换将失败。

不幸的是,具有关联类型的协议本身不能被视为具体类型,因此您在 AProtocol 中采用的方法将行不通。

在我看来,您有两个选择。将您的函数 return 类型更改为 B。毕竟,你总是 return a B

func sendB_() -> B {
    return B()
}

如果您想保持通用,请尝试

protocol BProtocol 
{
    associatedtype B

    init() // Needed to be able to do T() in generic function
}

func sendB_<T: BProtocol>() -> T{
    return T()
}

您需要将初始化程序添加到协议中,以确保 T 类型的实例始终存在。