热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

使用Swift中的Comparable扩展@objc协议-Extend@objcprotocolwithComparableinSwift

IamtryingtoextendmyprotocolOptionwithComparabletousesimple.sort()method.我正在尝试使用Compar

I am trying to extend my protocol Option with Comparable to use simple .sort() method.

我正在尝试使用Comparable扩展我的协议选项以使用简单的.sort()方法。

Below short example only with Equatable to show errors.

以下简短示例仅使用Equatable来显示错误。

@objc protocol Option: Equatable {
    var title: String { get }
    var enabled: Bool { get }
    var position: Int { get }
}

func ==(lhs: Option, rhs: Option) -> Bool {
    return lhs.position == rhs.position
}

The Option protocol must be marked as @objc or inherit from NSObjectProtocol because it will be used with UIKit.

Option协议必须标记为@objc或从NSObjectProtocol继承,因为它将与UIKit一起使用。

Errors:

  1. @objc protocol 'Option' cannot refine non-@objc protocol 'Equatable'

    @objc协议'选项'无法优化非@objc协议'Equatable'

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

    协议'选项'只能用作通用约束,因为它具有自我或相关类型要求

Do you have any suggestion how to solve this problem?

你有什么建议如何解决这个问题?

2 个解决方案

#1


4  

Equatable lives in the Swift world only, thus you cannot extend it to a protocol that will be used by Objective-C. Trying to do this results in error #1

只能在Swift世界中生活,因此您无法将其扩展为Objective-C将使用的协议。尝试这样做会导致错误#1

Protocols that have a Self requirement (i.e. at least one method from the protocol declaration contains Self) cannot be used as arguments to functions, or to variable declarations, only as arguments to a generic clause, e.g. func doSomething(argument: T).

具有Self要求的协议(即,协议声明中的至少一个方法包含Self)不能用作函数或变量声明的参数,仅作为泛型子句的参数,例如, func doSomething (参数:T)。

Removing Equatable from the Option protocol declaration, and declaring == as generic on Option will solve the compile errors. As for sorting, you can also overload the < operator, and sort via that operator (without needing to implement Comparable):

从Option协议声明中删除Equatable,并在Option上声明== as generic将解决编译错误。至于排序,你也可以重载 <运算符,并通过该运算符排序(无需实现comparable):

@objc protocol Option {
    var title: String { get }
    var enabled: Bool { get }
    var position: Int { get }
}

func ==(lhs: T, rhs: T) -> Bool {
    return lhs.position == rhs.position
}

func <(lhs: T, rhs: T) -> Bool {
    return lhs.position 

This allows you to pass objects that conform to the protocol to UIKit, and to also compare them within your swift code.

这允许您将符合协议的对象传递给UIKit,并在快速代码中对它们进行比较。

class A: NSObject, Option { .. }
class B: NSObject, Option { ... }

let a = A()
let b = B()
a == b  // compiles, and returns true if a and b have the same position
let c: [Option] = [a, b]
c.sort(<) // returns a sorted array by the `position` field

One important note regarding the sorting code above: if you don't specify the type for c, then the compiler infers its type as [NSObject], and the sort call will not compile due to ambiguity of the < operator. You need to explicitly declare c as [Option] to take advantage of the overloaded operator.

关于上面的排序代码的一个重要注意事项:如果你没有为c指定类型,那么编译器会将其类型推断为[NSObject],并且由于 <运算符的模糊性,排序调用将无法编译。您需要将c显式声明为[option]以利用重载运算符。

#2


2  

The issue can be fixed by the new protocol oriented programming features introduced in swift 2.0

这个问题可以通过swift 2.0中引入的新的面向协议的编程功能来解决

@objc protocol 'Option' cannot refine non-@objc protocol 'Equatable'

@objc协议'选项'无法优化非@objc协议'Equatable'

As the error states, the Equatable protocol is a swift protocol that you can't to Obj C context

正如错误所述,Equatable协议是一个swift协议,你不能对Obj C上下文

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

协议'选项'只能用作通用约束,因为它具有自我或相关类型要求

You can achieve this in the following way:

您可以通过以下方式实现此目的:

@objc protocol Option {
    var title: String { get }
    var enabled: Bool { get }
    var position: Int { get }
}

extension Equatable where Self : Option
{

}

extension Comparable where Self : Option
{

}

func ==(lhs: Option, rhs: Option) -> Bool
{
    return lhs.position == rhs.position
}

func <(lhs: Option, rhs: Option) -> Bool
{
    return lhs.position (lhs: Option, rhs: Option) -> Bool
{
    return lhs.position > rhs.position
}

And your class and implementation looks like:

你的类和实现看起来像:

class MyClass: Option
{
    @objc var title: String = ""
    @objc var enabled: Bool = true
    @objc var position: Int = 0

    init()
    {
    }

    convenience init(title : String, enabled : Bool, position: Int)
    {
        self.init()
        self.title    = title
        self.enabled  = enabled
        self.position = position
    }
}

let firstObj               = MyClass()
let secOndObj= MyClass()
let optionArray : [Option] = [firstObj, secondObj]

// Sort array of options
optionArray.sort(<)

推荐阅读
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文介绍了如何使用Express App提供静态文件,同时提到了一些不需要使用的文件,如package.json和/.ssh/known_hosts,并解释了为什么app.get('*')无法捕获所有请求以及为什么app.use(express.static(__dirname))可能会提供不需要的文件。 ... [详细]
  • 预备知识可参考我整理的博客Windows编程之线程:https:www.cnblogs.comZhuSenlinp16662075.htmlWindows编程之线程同步:https ... [详细]
  • Spring常用注解(绝对经典),全靠这份Java知识点PDF大全
    本文介绍了Spring常用注解和注入bean的注解,包括@Bean、@Autowired、@Inject等,同时提供了一个Java知识点PDF大全的资源链接。其中详细介绍了ColorFactoryBean的使用,以及@Autowired和@Inject的区别和用法。此外,还提到了@Required属性的配置和使用。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 本文介绍了深入浅出Linux设备驱动编程的重要性,以及两种加载和删除Linux内核模块的方法。通过一个内核模块的例子,展示了模块的编译和加载过程,并讨论了模块对内核大小的控制。深入理解Linux设备驱动编程对于开发者来说非常重要。 ... [详细]
  • VueCLI多页分目录打包的步骤记录
    本文介绍了使用VueCLI进行多页分目录打包的步骤,包括页面目录结构、安装依赖、获取Vue CLI需要的多页对象等内容。同时还提供了自定义不同模块页面标题的方法。 ... [详细]
  • node.jsrequire和ES6导入导出的区别原 ... [详细]
  • 本文整理了Java中com.evernote.android.job.JobRequest.getTransientExtras()方法的一些代码示例,展示了 ... [详细]
  • Bro是一款强大的网络安全工具,以及协议识别与统计的工具。Broisapowerfulnetworkanalysisframeworkthatismuchdifferentfro ... [详细]
author-avatar
花都色魔l文龙l_419
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有