swift - 您可以强制使用两种类型的泛型来确保这些类型不相同吗?

标签 swift generics where-clause swift5

是否可以限制以下泛型以确保 T1 和 T2 不是同一类型?

这是我正在尝试做的(但它不会编译)...

class Foo<T1, T2> where T1 != T2 {
}

鉴于这些类型...

class A{}
class B{}
class SubA : A{}

这些应该是有效的...

let w = Foo<A, B>()
let x = Foo<B, A>()

由于 Swift 的泛型不执行类型删除,我认为这也应该被允许(但如果不是也没关系。这只是为了讨论中的“完整性”)...

let y = Foo<A, SubA>

然而这不应该被允许...

let y = Foo<A, A>

现在我可以检查构造函数以确保是这种情况,但我想知道我是否可以在编译时使用“where”子句执行此操作,但我没有成功。

如果重要,使用 Swift 5。

最佳答案

这是可能的方法,编译时为相同类型生成错误并为不同类型传递错误。

测试:Xcode 11.2/Swift 5.1.2

generics type checking to avoid same types

class A {}
class B {}

class Foo<T1, T2> {
    private init() {}
}

extension Foo where T1: A, T2: B {
    convenience init(_ a: T1, _ b: T2) {
        self.init()
    }
}

extension Foo where T1: B, T2: A {
    convenience init(_ b: T1, _ a: T2) {
        self.init()
    }
}

和测试...

let test1 = Foo(A(), B())
let test2 = Foo(B(), A())
let test2 = Foo(A(), A()) // << Error: Ambiguous reference to initializer 'init(_:_:)'
let test2 = Foo(B(), B()) // << Error: Ambiguous reference to initializer 'init(_:_:)'
let test3 = Foo<String, String>() // Error: 'Foo<T1, T2>' initializer is inaccessible due to 'private' protection level

更新:Rob Napier 评论

enter image description here

关于swift - 您可以强制使用两种类型的泛型来确保这些类型不相同吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59814151/

相关文章:

mysql - SQL查询不清楚

ios - 事件指示器在 PHPhotoLibrary.sharedPhotoLibrary().performChanges 中 Action 缓慢

ios - 将 cocoapods 用于 facebookSDK 时找不到“FBSDKAppEvents.h”文件

ios - Swift 4 对成员 'jsonObject(with:options:)' 的引用不明确

c# - 将类型变量作为通用类型参数传递给静态类

php - MySQL PHP - 根据不同位置选择 WHERE

swift - 如何在 Swift 中使用数组和字典创建对象(如 js)

java - 在 Java 中使用泛型时出现空指针异常

swift - 一致性要求中的类型不引用泛型参数或关联类型

sql-server - 在分区表上选择查询