如果Equatable
为Box<T>
,我尝试将条件T
一致性添加到Equatable
类型。由于Swift.Void
不是Equatable
,Box<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
答案 0 :(得分:2)
我在编译过程中遇到错误:
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
,因为它没有利用Box
Equatable
为T
时Void
与==
的条件一致性(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
为Box
条件一致性表达了泛型类型的概念 仅在其类型参数满足时才符合特定协议 某些要求。
作为旁注,以下示例会产生预期结果:
Equatable
然而,特别是,如果T == ()
typedef
与()
Void
,即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
,则替换"use strict";
function Aircraft(a, b, c) {
this.manufacturer = a;
this.numberOfEngines = b;
this.costPerEngine = c;
}
// Prototype modifications should happen outside of the
// constructor function so that they are processed just
// once and not every time the constructor is invoked.
Aircraft.prototype.totalCost = function() {
return this.numberOfEngines * this.costPerEngine;
}
// At this point, the prototype is all set, so calling the
// constructor (which inherits from the prototype) creates
// a new object instance that has inherited the method.
let thunderbolt = new Aircraft('Republic', 1, 20000);
console.log(thunderbolt.totalCost());
到@ExceptionHandler
的条件一致性,崩溃了编译器:
/error
断言失败:(isActuallyCanonicalOrNull()&amp;&amp;“形成CanType 出于非规范类型!“),函数CanType,
file /Users/buildnode/jenkins/workspace/oss-swift-4.1-package-osx/swift/include/swift/AST/Type.h, 第393行。
...
编辑:显然是一个(现已解决的)错误: