使用 where 子句创建 Swift 扩展,该子句过滤采用泛型的结构

如何解决使用 where 子句创建 Swift 扩展,该子句过滤采用泛型的结构

我正在尝试在 Set 上创建一个使用 where 子句的扩展,以便它仅适用于我拥有的接受泛型的结构。但是我一直遇到关于它的错误,希望在结构中定义泛型

在此示例中,我收到以下错误,编译器提示建议我使用 <Any>对泛型类型“Test”的引用需要 <...>

struct Test<T> {
    var value : T
    func printIt() {
        print("value")
    }
}

extension Set where Element == Test {
    
}

但是,当我在结构中使用 <Any> 时,我收到此错误相同类型的约束类型“测试”不符合所需的协议“Equatable” >

extension Set where Element == Test<Any> {
    
}

关于如何让 where 子句接受我在泛型中使用的任何类型的测试结构的任何建议?

感谢您的帮助

解决方法

这是 Swift 类型系统的限制。没有具体的类型参数就无法谈论泛型类型,即使这些类型参数与类型的使用无关。对于这种特殊情况(所有可能的类型参数的扩展),我认为没有任何深层问题可以阻止它。它是 parameterized extensions 的一个更简单的版本,这是一个理想的功能。只是不支持 (though there is an implementation in progress)。

今天解决这个问题的标准方法是使用协议。

首先,进行一些与您的问题无关的清理工作(您可能已经知道了)。您的示例要求测试为 Hashable

struct Test<T: Hashable>: Hashable {
    var value : T
    func printIt() {
        print("value")
    }
}

制定一个协议,需要任何你想要的扩展部分,并使测试符合:

protocol PrintItable {
    func printIt()
}

extension Test: PrintItable {}

然后使用协议而不是类型:

extension Set where Element: PrintItable {
    func printAll() {
        for item in self { item.printIt() }
    }
}

let s: Set<Test<Int>> = [Test(value: 1)]

s.printAll()  // value

就您收到的错误消息再做一个说明。第一个错误,要求你添加 Any 实际上只是抱怨 Swift 不能谈论非参数化泛型,并在它不知道建议什么类型时建议它是后备类型:Any。

但是 Set<Any> 不是“任何类型的 Set”。它是一个 Set,其中 Element == Any。所以 Any 必须是可哈希的,这是不可能的。并且 Set<Int> 不是 Set<Any> 的子类型。有完全不同的类型。所以这些错误有点令人困惑,会让你走上一条毫无帮助的道路。

,

这是不可能的。 where 子句需要特定的数据类型,除非我指定更具体的内容,例如 Test,否则简单地传递 Test<String> 是行不通的。

感谢 Joakim 和 flanker 在评论中回答问题

,

如果您想使用 where 子句为 Set 添加扩展,您的测试必须确认Hashable 协议。 您的结构必须如下所示。

struct Test<T: Hashable> : Hashable {
    var value : T
    func printIt() {
        print("value")
    }
    func hash(into hasher: inout Hasher) {
        hasher.combine(value.hashValue)
    }
}

所以你不能使用Any作为你的扩展,你必须指定确认Hashable协议的类型.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?