首页 > 解决方案 > 协议“形状”只能用作通用约束,因为它具有自身或相关类型要求

问题描述

试图创建我的抽象:

protocol ElectricallyDrawable {
    func isConnected() -> Bool

    func showPowerAnimation(using shape: Shape) <-- Error
}

Protocol 'Shape' can only be used as a generic constraint because it has Self or associated type requirements

首先,我知道这个问题已经被问了无数次。

我理解这个错误,如果我知道Shape有一个associatedtype我会预料到的..

所以..

我不是在问为什么我会收到这个错误

而我的问题是:

应该如何弄清楚associatedtype每个protocol

因为我已经搜索了文档和定义,什么都没有。

如果我们知道associatedtype命名法,那么我们可以将其设置为具体类型……例如……

如果我知道:

protocol Shape {
      associatedtype Line 
}

然后我可以像这样使用它:

protocol ElectricallyDrawable {
    typealias Line = Rectangle <-- This would stop the error 
    
    func isConnected() -> Bool

    func showPowerAnimation(using shape: Shape) 
}

标签: swiftswiftui

解决方案


所以我要回答两个问题

1)你应该如何获得associatedtype协议?

有两种选择。选项 a:您正在实现接口:

struct Resistor: ElectricallyDrawable {
    typealias Line = Rectangle
}

在这种情况下,很明显你的线是一个矩形,因为你定义了它。

选项 b:您正在扩展接口:

extension ElectricallyDrawable where Line == Rectangle {
    //...
}

或者

extension ElectricallyDrawable {
    func x() {
        if Line.self == Rectangle.self {
            //...
        }
    }
}

因此,无论哪种方式,您都只需associatedtype按其名称“获取”。

2)你会怎么做?

好吧,有两种选择。你可以associatedtype像这样走:

protocol ElectricallyDrawable {
    
    associatedtype Line: Shape
    
    func isConnected() -> Bool

    func showPowerAnimation(using shape: Line)
}

您将自己限制为associatedtype(您正在使用的实际类型)是一个形状,或者您将泛型添加到函数本身:

protocol ElectricallyDrawable {

    func isConnected() -> Bool

    func showPowerAnimation<S>(using shape: S) where S: Shape
}

无论哪种方式都很好,最好的方法可能取决于您的用例


推荐阅读