我正在尝试将条件Equatable一致性添加到类型sayBox<T>,如果TEquatable。由于Swift.Void不是EquatableBox<Void>不是Equatable

struct Box<T> {
    //...
}

extension Box: Equatable where T: Equatable {

}

我可以像下面这样定义一个新类型作为解决方案:
public struct Empty: Equatable {

}

然后用Box<Empty>而不是Box<Void>这样就行了。但是,想知道是否有其他方法来引入一种新的类型。
更新:
我试过了,但没用
struct Box<T> {
    //...
}

extension Box: Equatable where T: Equatable {
    static func ==(lhs: Box<T>, rhs: Box<T>) -> Bool {
        return true
    }
}
extension Box where T == Void {
    static func ==(lhs: Box<T>, rhs: Box<T>) -> Bool {
        return true
    }
}

编译期间出错:FooBarBaz does not conform to protocol Equatable
enum FooBarBaz: Equatable {
    case success(box: Box<Void>)
    // case success(box: Box<Int>) compiles as expected.
}

请注意,我使用的是Swift 4.1。

最佳答案

编译期间出错:FooBarBaz不符合协议Equatable
这一半的答案集中在解释为什么你自己尝试过的方法还不能奏效。
目前,有一个条件符合性的限制,将限制您使用这种特定的技术来实现您的目标。引用SE-0143: Conditional conformances,在Swift 4.1中实施:
多重符合性
Swift已经禁止试图使同一类型符合的程序
同一协议两次,例如:

对多重符合性的现有禁令扩展到有条件的
符合性,包括在
两种不同的方式。

部分overlapping conformances描述了
由多个符合引入的复杂性,以证明它们
排除在本提案之外。后续建议可能会引入
支持多个符合项,但也可能包括
相关特征,如正交于
条件符合性。
它不允许我们构造多个条件一致性,例如:

struct Box<T> { }

extension Box: Equatable where T == Void {
    static func ==(lhs: Box<T>, rhs: Box<T>) -> Bool {
        return true
    }
}

// error: redundant conformance of 'Box<T>' to protocol 'Equatable'
extension Box: Equatable where T: Equatable {
    static func ==(lhs: Box<T>, rhs: Box<T>) -> Bool {
        return true
    }
}

另一方面,如果我们看看你自己的例子:
struct Box<T> { }

extension Box: Equatable where T: Equatable {
    static func ==(lhs: Box<T>, rhs: Box<T>) -> Bool {
        return true
    }
}

extension Box where T == Void {
    static func ==(lhs: Box<T>, rhs: Box<T>) -> Bool {
        return true
    }
}

// error: type 'Void' does not conform to protocol 'Equatable'
func foo<T: Equatable>(_ _: T) { print(T.self, "is Equatable") }
foo(Box<Void>())

Swift准确地识别出Box<Void>不是Equatable:扩展名Box where T == Void并不意味着Box<Void>符合Equatable,因为当BoxEquatable时,它不利用TVoid的条件一致性(它只在==T的情况下提供Void方法)。
条件一致性表达了一个概念,即泛型类型将
仅当其类型参数满足时符合特定协议
某些要求。
作为补充说明,下面的示例产生预期结果:
struct Box<T> { }

extension Box: Equatable where T == () {
    static func ==(lhs: Box<T>, rhs: Box<T>) -> Bool {
        return true
    }
}

func foo<T: Equatable>(_ _: T) { print(T.self, "is Equatable") }
foo(Box<Void>()) // Box<()> is Equatable

然而,特别是,将BoxEquatableifT == ()的条件一致性替换为typedef的条件一致性,即使编译器崩溃:
struct Box<T> { }

extension Box: Equatable where T == Void {
    static func ==(lhs: Box<T>, rhs: Box<T>) -> Bool {
        return true
    }
}

func foo<T: Equatable>(_ _: T) { print(T.self, "is Equatable") }
foo(Box<Void>()) // compiler crash

断言失败:(isactuallicanonicalornull()&&“形成cantype
超出了非规范类型!“),函数类型,
文件/users/buildnode/jenkins/workspace/oss-swift-4.1-package-osx/swift/include/swift/ast/type.h,
第393行。

编辑:显然是一个(现在解决的)错误:
SR-7101: Compiler crash when implementing a protocol for an enum using generics

10-08 05:47