使用关联类型和泛型时出错

2023-12-22

以下代码给我一个在线错误return p.foo(self)。错误说:'P' does not have a member named 'foo'.

protocol P {
  typealias T
  func foo(c: C<T>) -> T
  func foo2() -> T
}

class C<T> {
  var p: P
  init (p: P) {
    self.p = p
  }
  func bar() -> T {
    return p.foo(self);
  }
}

协议P定义一个关联类型,该类型应与任何专门的 C 类型正确匹配。我错过了什么吗?或不?


在回答问题之前,我将稍微重命名类型以使问题更清晰:

protocol P {
  typealias ElementType
  func foo(c: C<ElementType>) -> ElementType
  func foo2() -> ElementType
}

class C<T> {
  var p: P
  init (p: P) {
    self.p = p
  }
  func bar() -> T {
    return p.foo(self)
  }
}

在这种情况下,您会收到三个编译器错误:

error: <EXPR>:8:12: error: protocol 'P' can only be used as a generic constraint because it has Self or associated type requirements
    var p: P
           ^
<EXPR>:9:14: error: protocol 'P' can only be used as a generic constraint because it has Self or associated type requirements
    init (p: P) {
             ^
<EXPR>:13:16: error: 'P' does not have a member named 'foo'
        return p.foo(self)
               ^ ~~~

有趣的是第一个/第二个(他们指出了同样的问题):“协议‘P’只能用作通用约束,因为它具有 Self 或关联类型要求”。 所以问题出在关联类型上。在当前配置中,您指定初始值设定项的参数和变量的类型为 P。但由于您为 P 指定了关联类型,因此该类型不够具体,无法用作正确的类型。仅实际指定内容的子类型ElementType是可以使用的。但是,您可以指定一个必须是 P 子类型的通用参数。对于初始化程序,您可以编写

init <S:P>(p: S) {
    self.p = p
}

这将消除初始化程序的编译器错误。现在编译器知道参数必须是 P 的子类型,并且有效的子类型始终指定 ElementType 是什么,所以它很高兴。

但这对你来说这行没有帮助:

var p: P

您仍然无法使用不完整类型P这里。你可能想使用S,但目前之间没有任何联系S在初始化程序中,您将使用 S 作为变量的类型,但它们显然需要相同。 是时候向您的类引入第二个通用参数了:

class C<T, S:P> {
    var p: S
    init (p: S) {
        self.p = p
    }
    func bar() -> T {
        return p.foo(self)
    }
}

几乎完成了,现在您已经正确指定了可用于变量的类型。但你的协议规范不正确:

func foo(c: C<ElementType>) -> ElementType

C 现在需要两个参数,您需要在此处指定它们。我们想在这里使用`C,但我们不能:

错误::3:17:错误

: type 'P' does not conform to protocol 'P'
    func foo(c: C<ElementType, P>) -> ElementType
                ^
<EXPR>:2:15: note: associated type 'ElementType' prevents protocol from conforming to itself
    typealias ElementType

Since P未指定关联类型ElementType它不正确地符合P并且不能用在符合类型的地方P是需要的。但有一个很好的特殊类型:Self。它引用了实现协议的实际类型,因此我们可以编写以下内容:

protocol P {
    typealias ElementType
    func foo(c: C<ElementType, Self>) -> ElementType
    func foo2() -> ElementType
}

现在我们指定由任何确认类型实现的 foo 函数实际上采用具有指定 ElementType 和实现类型本身的 C。很想,不是吗?

但我们还没有完全完成,最后一个错误仍然存​​在:

error: <EXPR>:13:18: error: cannot convert the expression's type 'T' to type 'S.ElementType'
        return p.foo(self)

此时编译器知道以下内容:

  • p.foo(self) 返回以下内容ElementType of S
  • 函数 bar() 应该返回某种类型T

但没什么可说的ElementType and T实际上是相同的,因此无法确定这是否有效并有抱怨。所以我们真正想要的是ElementType of S总是一样T我们可以指定这一点:

class C<T, S:P where S.ElementType == T> {

完整代码:

protocol P {
    typealias ElementType
    func foo(c: C<ElementType, Self>) -> ElementType
    func foo2() -> ElementType
}

class C<T, S:P where S.ElementType == T> {
    var p: S
    init (p: S) {
        self.p = p
    }
    func bar() -> T {
        return p.foo(self);
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用关联类型和泛型时出错 的相关文章

  • 从字典创建 Swift 对象

    如何根据 Swift 字典中的查找值动态实例化类型 希望这对其他人有用 我们需要进行一些研究才能弄清楚这一点 目标是避免巨大的 if 或 switch 语句从值创建每个对象类型的反模式 class NamedItem CustomStrin
  • 使用 PDFOutline 将 TOC 添加到 Swift/Cocoa 中的 PDFDocument

    我正在开发一个小程序 将多个单页 PDF 合并到一个多页 PDF 中 我正在 Swift4 MacOS Cocoa 中工作 但我一生都无法在 Swift 中找到任何类型的示例来创建大纲 仅遍历现有的大纲 我对此非常熟悉 使用对文档的最佳猜测
  • Swift 单元测试 - 如何断言 CGColor 是它应该的样子?

    使用 Xcode V7 2 尝试进行单元测试 需要验证是否已设置正确的颜色 并收到以下消息 Cannot invoke XCTAssertEqual with an argument list of type CGColor CGColor
  • Facebook 登录打开错误的应用程序

    我正在尝试使用 facebook 实现应用程序的登录 但每次我尝试登录时 它都建议打开错误的应用程序 我尝试了一些在这里找到的东西 但没有成功 在 Facebook 的开发者页面上我添加了一个后缀 我的 plist 如下 有谁知道发生了什么
  • 当 tableview 滚动时 UISegment 值发生变化

    我正在使用 UISegmentControl 在表格视图中显示客观类型问题 但是 如果我在任一单元格中选择一个段 那么如果我滚动 某些段值就会发生更改 我不知道如何解决这个问题 请指导我 细胞尺寸 160px 段色调颜色 蓝色 Coding
  • 排除 Realm 模型类

    我的应用程序中配置了两个领域文件 我想存储我的Log将模型与其他模型分开保存为单独的文件 我的问题是我也看到了我的Log我不想要的默认 Realm 文件中的模型类 如何从给定的 Realm 文件中排除特定的模型类 我使用主 Realm 文件
  • 可以转换为 Swift 5

    我在 Xcode 10 2 中收到此警告 可以转换为 Swift 5 当我单击此错误时 它会打开此窗口 当我们点击Next会发生什么 swift 的当前版本是 swift5 仅在 Xcode 10 2 中受支持 而您在 Xcode 10 2
  • geocoder.geocodeAddressString 今天不再适用于快速更新

    https developer apple com library prerelease mac releasenotes General APIDiffsMacOSX10 11 Swift CoreLocation html https
  • iOS swift 应用程序启动时出现黑屏

    我有个问题 当我启动我的应用程序时 会看到黑屏几秒钟 然后出现启动屏幕 我的启动画面不是默认的 我使用了视图控制器 因为我的启动画面有一个动画 我搜索了一个解决方案 我得到了这个 在我的闪屏加载 iPhone 之前出现黑屏 https st
  • 无法在 Swift 中获取 plist URL

    我对这个真的很困惑 网络上有很多问题询问 如何从 Swift 中的 plist 文件获取信息 并且到处都发布了相同的答案 let path NSBundle mainBundle pathForResource Config ofType
  • 当我启动项目时没有 viewcontroller.swift 文件 [重复]

    这个问题在这里已经有答案了 我尝试启动该项目并使用视图控制器 但我没有看到它 仅appdelegate和scenedelegate和contentview 下面的代码应该添加到视图控制器中 但我不知道添加到哪里 它不断给我一条错误消息 指出
  • 将 NSDate 转换为 SWIFT 中具有特定时区的字符串

    在我的核心数据库中 我有一个带有 NSDate 属性的 新闻 实体 我的应用程序遍布全球 新闻已发布2015 09 04 22 15 54 0000法国时间 GMT 2 为了保存日期 我将其转换为 UTC 格式 let mydateForm
  • iOS 上每个选项的带有图像的操作表

    有没有办法在 iOS 上将图像添加到操作表中 与苹果在应用程序商店或苹果音乐应用程序上所做的一样 我对苹果文档的基本搜索表明我没有在操作表中子类化或添加子视图 UIActionSheet 并非设计为子类化 也不应向其层次结构添加视图 苹果文
  • 在 Swift 3 中单击和双击 UITableViewCell

    我在 TableView Cell 上有故事板 segue 我用它来在单元格单击中传输到另一个 VCdidSelectRowAt方法 现在我双击了TapGestureRecognizer处理手机上的点击问题 问题是 单击时 segue 正在
  • 在 Swift 中将 Int 转换为 UInt32

    我正在制作一个 Tcp 客户端 因此使用CFStreamCreatePairWithSocketToHost它期望第二个参数为 UInt32 这是我正在尝试做的事情的示例 func initNetwork IP String Port In
  • 如何在 Swift 中使用 CGFloat?

    var posinonY Float Float y Float pipeDown size height Float verticalPipeGap pipeDown position CGPointMake 0 0 Float posi
  • iOS 内存警告

    我正在尝试使用从 Parse 数据库下载的图像填充集合视图 但我收到内存警告 然后偶尔崩溃 有谁知道其他应用程序如何设法呈现这么多图像而不崩溃 有人可以告诉我如何优化我已有的东西吗 这是所有相关代码 https gist github co
  • Swift 如何设计 UIWebView 在 Story Board 中自动调整全屏大小

    我在 StoryBoard 中设计了一个 320x500 的 UIWebView 但是当在 Iphone 6 Plus 模拟器中运行时 我想要这个 webview 全屏或随设备屏幕缩放 如何在故事板中制作它 我在 ViewDidLoad 中
  • 打印附加结构(swift 4)

    我有三个 textifled 用于将数据附加到结构中 如何打印我附加的内容 现在我收到一条错误消息 import UIKit class ViewController UIViewController IBOutlet var c UITe
  • 播放(非库)Apple Music 内容 - 请求失败

    我正在尝试使用以下代码播放专辑 let predicate MPMediaPropertyPredicate value 1459938538 forProperty MPMediaItemPropertyAlbumPersistentID

随机推荐

  • 如何向 OxyPlot 添加新点?

    这是 Oxyplot 官方页面显示的代码 命名空间 WpfApplication2 using System Collections Generic using OxyPlot public class MainViewModel publ
  • 将静态 iOS 框架链接到应用程序和 XCTest 目标时出错

    我有一个结合了 Objective C 和 Swift 的应用程序 它有一个 XCTest 目标 我有一个用 Objective C 编写的静态框架 它链接到主目标并由主目标和测试目标使用 我测试了 3 种不同的情况 其中两种情况可以编译但
  • 安全的Javascript加密库?

    我正在搜索一个提供安全加密的 JavaScript 库 客户端必须生成密钥 所有上传到服务器的数据都被加密 所有下载的数据都被解密 我需要一个经过身份验证的加密方案 仅 CTR 或 CBC 是不够的 我听说过 sjcl 但似乎 sjcl 只
  • 重复序列化和反序列化会创建重复的项目

    大家好 我的 json 序列化有问题 我正在 Unity 下使用 Json NET 包 我正在寻找一个数据库 该数据库可在我的应用程序上编辑 并通过 wwwForm 和 php 文件存储在我的服务器上 我可以毫无问题地创建它并将其推到网上
  • 使用 PHP 解析 HTML 并获取 h2 之后的下一个 h2 之前的所有 h3

    我正在寻找文章中的第一个 h2 找到后 查找所有 h3 直到找到下一个 h2 冲洗并重复 直到找到所有标题和副标题 在您立即将此问题标记或关闭为重复解析问题之前 请注意问题标题 至于这与基本节点检索无关 我已经把那部分记了下来 我在用DOM
  • 是否可以在Lua中模拟bind?

    给定一个只有一个参数的lua函数 是否可以将此参数绑定到一个固定值以获得一个没有参数的函数 更一般地说 如何将 lua 函数的某些输入参数绑定到某些值 是的 这几乎可以用任何具有一流值函数的语言来完成 function f1 a retur
  • 如何迭代多个json字典来检查相同类型key的值?

    我希望能够在多个 json 字典中获取 delta 的值 如果有什么改变的话 我正在使用 kivy 的 JsonStore 当我按下启动 check streak 函数的按钮时 我得到 NameError name delta is not
  • 从 Nodejs 脚本获取 Microsoft GRAPH 访问令牌

    这个问题建立在如何从 Node 脚本获取 Microsoft Graph API 访问令牌 https stackoverflow com questions 50613628 how to get microsoft graph api
  • 如何在Python交互模式下撤消True = False? [复制]

    这个问题在这里已经有答案了 所以我尝试了内德 戴利在他的回答中提到的 邪恶 的事情here https stackoverflow com questions 12765833 counting the number of true boo
  • 为什么我的 if 条件不接受 java 中的整数?

    目前我正在使用 int a 10 if a 20 printf TRUE else printf false 以 C 语言打印值TRUE 但如果是java int a 10 if a 20 System out println TRUE e
  • HttpSelfHostServer 和 HttpContext.Current

    我正在开发一个自托管 ASP NET Web api 应用程序 一切都很好 但现在我很挣扎HttpContext 我需要保存客户端的会话信息 但HttpContext Current始终为空 所以很明显我的HttpSelfHostServe
  • xlCellTypeLastCell 给出错误的值

    我很难从中获得准确的值SpecialCells xlCellTypeLastCell 在 Excel VBA 中 以下代码应输出 TrackedItems 工作表中第一个空行的行号 该工作表有 8 行 但代码输出 25 应输出 9 empt
  • 如何让Arduino在每天规定的时间执行某项任务?

    我是一名学生 而且是 Arduino 的新手 我正在尝试做一个自动植物浇水系统每天给植物浇水两次 有没有办法让Arduino在每天规定的时间准确执行任务 然后将其设置为睡眠模式 每天正好在规定的时间 如果您的 Arduino 采用内部 RC
  • 将绘图保存为 R 对象并在网格中显示

    在下面的可重现示例中 我尝试为 ggplot 分布图创建一个函数并将其保存为 R 对象 目的是在网格中显示两个图 ggplothist lt function dat var1 if is character var1 var1 lt wh
  • 无法部署 Cloud ML 模型

    为什么我尝试将经过训练的模型部署到 Google Cloud ML 但出现以下错误 Create Version failed Model validation failed Model metagraph does not have in
  • ArangoDB 的 SPARQL 接口

    对于 Arangodb 我知道它自己的查询语言 AQL 据我所知 还有一个附加组件 允许使用 Gremlin 进行图形遍历等 在我的一个项目中 我们强烈使用 SPARQL 因此 有没有办法使用 SPARQL 作为 Arangodb 的查询语
  • Microsoft.Diagnostics.Tracing.EventSource 与 RabbitMQ.Client.dll 异常

    为什么我会收到以下错误以及如何修复它 RabbitMQ Client dll 中发生 System IO FileLoadException 类型的未处理异常 无法加载文件或程序集 Microsoft Diagnostics Tracing
  • 批量操作的 firebase cloud firestore 定价

    https firebase google com docs firestore manage data transactions https firebase google com docs firestore manage data t
  • iOS 的 Facebook 签名请求 (HMAC SHA256)

    几周来我一直在尝试为 iOS 上的 Facebook 签名请求生成 HMAC SHA256 我非常需要帮助 Facebook 签名的请求有两个部分 用句点分隔 第一部分是有效负载的 HMAC256 第二部分是有效负载的 Base64 编码字
  • 使用关联类型和泛型时出错

    以下代码给我一个在线错误return p foo self 错误说 P does not have a member named foo protocol P typealias T func foo c C