协议相关的类型别名分配编译错误 [英] protocol associated type typealias assignment compile error

查看:139
本文介绍了协议相关的类型别名分配编译错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码:

protocol SomeProtocol {
    typealias SomeType = Int // used typealias-assignment

    func someFunc(someVar: SomeType)
}

class SomeClass: SomeProtocol {
    func someFunc(someVar: SomeType) {
        print(someVar)
    }
}

给出编译时错误:

使用未声明的类型"SomeType"

Use of undeclared type 'SomeType'

typealias SomeType = Double添加为SomeClass可解决该错误.

Adding, say typealias SomeType = Double, to the SomeClass resolves the error.

问题是,虽然协议关联类型声明的 typealias-assignment 部分(可选的btw)有什么意义?

The question is, what's the point of typealias-assignment part (which is optional btw) of protocol associated type declaration though?

推荐答案

在这种情况下,将Int分配给typealias等于没有分配,因为它会被符合您的类型覆盖:

In this case the assignment of Int to the typealias is equal to no assignment because it gets overridden by your conforming type:

// this declaration is equal since you HAVE TO provide the type for SomeType
protocol SomeProtocol {
    typealias SomeType

    func someFunc(someVar: SomeType)
}

这样的分配为SomeType提供了默认类型,该默认类型会被您在SomeClass中的实现所覆盖,但是对于协议扩展特别有用:

Such an assignment provides a default type for SomeType which gets overridden by your implementation in SomeClass, but it is especially useful for protocol extensions:

protocol Returnable {
    typealias T = Int // T is by default of type Int
    func returnValue(value: T) -> T
}

extension Returnable {
    func returnValue(value: T) -> T {
        return value
    }
}

struct AStruct: Returnable {}

AStruct().returnValue(3) // default signature: Int -> Int

仅通过遵循协议而不指定T的类型,即可免费获得该功能.如果要设置自己的类型,请在结构体中写入typealias T = String // or any other type.

You get the function for free only by conforming to the protocol without specifying the type of T. If you want to set your own type write typealias T = String // or any other type in the struct body.

有关所提供代码示例的其他说明

您解决了该问题,因为您明确指出了该参数具有哪种类型. Swift还可以推断出您使用的类型:

You solved the problem because you made it explicit which type the parameter has. Swift also infers your used type:

class SomeClass: SomeProtocol {
    func someFunc(someVar: Double) {
        print(someVar)
    }
}

因此,将协议的SomeType推断为Double.

So SomeType of the protocol is inferred to be Double.

另一个例子,您可以看到类声明中的SomeType没有引用协议:

Another example where you can see that SomeType in the class declaration doesn't refer to to the protocol:

class SomeClass: SomeProtocol {
    typealias Some = Int
    func someFunc(someVar: Some) {
        print(someVar)
    }
}

// check the type of SomeType of the protocol
// dynamicType returns the current type and SomeType is a property of it
SomeClass().dynamicType.SomeType.self // Int.Type
// SomeType gets inferred form the function signature

但是,如果您这样做:

protocol SomeProtocol {
    typealias SomeType: SomeProtocol

    func someFunc(someVar: SomeType)
}

SomeType必须为SomeProtocol类型,该类型可用于更明确的抽象和更静态的代码,而这是

SomeType has to be of type SomeProtocol which can be used for more explicit abstraction and more static code whereas this:

protocol SomeProtocol {
    func someFunc(someVar: SomeProtocol)
}

将被动态调度.

这篇关于协议相关的类型别名分配编译错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆