简体   繁体   English

具有关联类型的返回协议

[英]return protocol with associated type

how to return protocol with associated type? 如何返回关联类型的协议?

protocol AProtocol {

}

class A: AProtocol {

}

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

it works. 有用。

but

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
    }
}

i want to return 'return B()' in function 1 is it possible? 我想在函数1中返回'return B()'吗?

You are trying to return BProtocol in case 1. The thing is PAT (Protocol with Associated Types) are not exactly types. 您试图在情况1中返回BProtocol 。问题是PAT(具有关联类型的协议) 不是完全类型。 They act as sort of placeholder for types. 它们充当类型的占位符。 So you cannot return BProtocol directly. 因此,您不能直接返回BProtocol

Swift 5.1 迅捷5.1

I am not 100% sure but I think in the next iteration of swift (5.1), they have introduced opaque types which allow the functionality you desire. 我不确定100%,但是我认为在swift(5.1)的下一个迭代中,他们引入了不透明类型 ,可以使用您想要的功能。

In that case you would be able to call it like this: 在这种情况下,您可以这样称呼它:

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

In this function 在此功能

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

you cannot return a B as a T because the person who uses the function defines what T is, not you and T can be any type that conforms to Protocol For example, I could do this: 您不能将B作为T返回,因为使用该函数的人定义了T是什么,而不是您,并且T可以是符合Protocol任何类型。例如,我可以这样做:

class C: BProtocol 
{
    typealias B = Float
}

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

By doing that, I am setting T to be a C and the forced typecast in sendB_() will fail. 通过这样做,我将T设置为C并且sendB_()的强制类型转换将失败。

Unfortunately, protocols with associated types cannot, themselves, be treated like a concrete type, so the approach you took with AProtocol will not work. 不幸的是,具有关联类型的协议本身不能被视为具体类型,因此您使用AProtocol采取的方法将行不通。

As I see it, you have two options. 如我所见,您有两个选择。 Change your function return type to B . 将函数返回类型更改为B After all, you always do return a B 毕竟,您总是会返回B

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

If you want to keep it generic, try 如果要使其通用,请尝试

protocol BProtocol 
{
    associatedtype B

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

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

You need to add the initialiser to the protocol to make sure that an instance of type T always exists. 您需要将初始化程序添加到协议中,以确保类型T的实例始终存在。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM