协变“Self”类型无法从存储的属性初始值设定项中引用

2024-04-19

在下面的代码中,我不明白为什么在使用时会出现上述错误Self()?如果我将其替换为,代码就可以正常工作Fireman() .

final class Fireman {

    var numOfServices = 0

    private init(){}
    static var shared = Self() <-------- Here !!!

    func extinguishFire() {
        self.numOfServices += 1
        print("Spraying water...\(self.numOfServices)")
    }
}

这也是我必须给班级打分的原因final是因为,如果没有这个错误消息,我必须包含一个required初始化程序(当我这样做时,我再次收到错误,因为我的初始化程序是private)。因此,为了避免进一步子类化,尽管违背我的意愿,我宣布该类为最终类


这非常类似于返回 Self 的协议函数 https://stackoverflow.com/questions/25645090/protocol-func-returning-self,但足够不同,可能值得单独回答。这里有两个问题。

第一个问题是为什么你需要final。正如上面的问题一样,问题在于您做出的承诺编译器无法证明您会遵守。

考虑以下子类:

class LocalFireman: Fireman {
    let zipcode: String
    init(zipcode: String) { self.zipcode = zipcode }
}

什么应该LocalFireman.shared返回?它无法返回消防员。你说它必须返回 Self(即 LocalFireman)。并且它不能返回LocalFireman,因为它没有用于初始化的邮政编码。那么现在怎么办?

Swift 不会让你陷入这个困境,因为它要求你要么确定特定的类型shared(即它永远是Fireman,即使你在子类上调用它),或者你需要承诺不会有子类,或者你需要要求所有子类都实现init:

required init() {}

好吧,但你已经做到了这一点。你标记了final,它仍然抱怨。现在您遇到了编译器限制。整个要点Self是协方差;它是调用时的动态类型,而不是上下文中的静态类型 https://forums.swift.org/t/pitch-adding-a-self-type-name-shortcut-for-static-member-access/2056。这不仅仅是表达“我的类型”的便捷方式,而且这是一种选择(尽管我认为这是可以改变的)。它意味着“我的协变类型”,即使您处于不可能有任何子类型的情况。

综上所述,鉴于privateinit,我很困惑你为什么说标记它final是“违背我的意愿”。我摔倒init是私有的,无论如何都不能子类化,所以看起来你想要一个最终类,如果是这样,那么只需将类名放在它所在的位置即可。Self不是为了这个问题(今天)。

这就留下了一个悬而未决的问题:为什么你不能使用必需的 init 来做到这一点。Self作为“类的类型”和Self因为“符合协议的事物类型”被视为同一事物。所以你不能只在课堂上考虑这个问题;任何东西都可以“继承”(遵守)协议。所以Self可以潜在地引用一个结构。结构可以是任意大小。因此允许存储的属性为类型Self产生内存布局问题。 (我也不认为 Swift 承诺类将始终作为指针实现,因此这可能会导致类出现同样的问题,至少在原则上是这样。)

您可以返回类型的值Self来自函数,但你不能将其放入存储属性中(静态和非静态属性都是如此),并且 Swift 也不允许它们用于计算属性(我认为这只是为了一致性)。因此,以下内容是允许的(实际上很有用):

class Fireman {
    required init() {}
    static func make() -> Self { return Self() }
}

这就是Self is for.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

协变“Self”类型无法从存储的属性初始值设定项中引用 的相关文章

  • 如何快速防止标签中出现孤儿?

    我有一个可以有一两行的标签 如果它有两行 我希望第二行至少有两个 或者可能三个 单词 而不仅仅是一个 关于如何使用 swift 实现这一点有什么想法吗 提前致谢 Daniel 编辑 我删除了我愚蠢的第一个想法 这些想法并没有真正的帮助 好吧
  • Mapkit 在 IOS 13 中使用过多的 CPU

    最近 在一些用户更新到 iOS 13 x 后 我的 iOS 应用程序开始频繁崩溃 在 iOS 12 x 中没有出现该问题 我正在使用 Mapkit 渲染一些 MKPolygons 和 MKPolylines MKPolylines 被删除并
  • Swift - 将图像插入 PDF 不再适用于 iOS 13

    目前正在开发在我的贷款计算器应用程序上导出 PDF 的功能 我有一个预览屏幕 可以在您保存 PDF 之前显示它 预览屏幕由带有 html 的 webView 组成 其中包含占位符 我能够成功地将图像插入到正确的占位符上 并将其显示在 PDF
  • 弱变量中间为零

    弱变量什么时候变为零 weak var backgroundNode SKSpriteNode texture SKTexture image initialBackgroundImage backgroundNode position C
  • 未捕获的 Kotlin 异常:kotlin.native.In CorrectDereferenceException:非法尝试访问非共享

    我尝试使用 Kotlin MPP Multiplatform 开发 Android 和 iOS 之间的共享库 但我面临着 iOS 中线程的问题 对于我在 iOS 中的应用程序 我在主线程中建立了对象 但它可能调用其他线程中的函数并抛出此异常
  • Swift 中的 quitFirstResponder

    我怎样才能用Apple的新语言实现它 Objective C 代码 void touchesBegan NSSet touches withEvent UIEvent event for UIView view in self view s
  • 在 iOS 上使用 HEVC 编码器输出视频尺寸巨大

    我有一个项目 目前使用 H 264 编码器在 iOS 上录制视频 我想尝试在 iOS 11 中使用新的 HEVC 编码器来减小文件大小 但发现使用 HEVC 编码器会导致文件大小急剧膨胀 GitHub 上的一个项目显示了该问题 它使用 H
  • Swift:无法为“[UIViewController]”类型的值添加下标?

    我试图弄清楚如何在 Xcode 7 iOS9 上的 Swift 中解决此问题 并且我也遇到此错误 无法为 UIViewController 类型的值添加下标 索引类型为 Int 任何建议表示赞赏 谢谢 My code func indexP
  • iOS 11 浮动 TableView 标题

    有一个应用程序包含多个部分 展开 时每个部分有几行 折叠 时没有 每个部分都有一个部分标题 使用以下子类重用它们UITableViewHeaderFooterView等等 到目前为止一切顺利 然后在 iOS 11 中 我使用了可视化调试器
  • let/var 如何解决可变性? [复制]

    这个问题在这里已经有答案了 我没有任何问题 我只是想对有关可变性的问题进行一些澄清 在 Objective C 中我们会使用例如NSMutableArray得到一个可变数组和NSArray得到一个不可变的 我对两者的内部运作了解不多 但据我
  • Swift:检查 UISearchBar.text 是否包含 url

    如何检查 UISearchBar text 是否包含 URL 我想做这样的事情 if searchBar text NSTextCheckingType Link 但我收到错误 String is not convertible to NS
  • 带约束的嵌套集合视图的意外行为 (Swift 4)

    我的表格视图中有一个单元格 其中包含水平分页集合视图 该集合视图的每个页面内都有一个垂直集合视图 为了避免 滚动滚动 问题 我在垂直集合视图中禁用了垂直滚动 垂直集合视图的单元格计数不是静态的 可以是任意数字 因此 这会产生一个问题 集合视
  • 使用 BGTaskScheduler 进行后台获取与调试模拟完美配合,但在实践中却不起作用

    我在 appDelegate 的 didFinishLaunchingWithOptions 中注册后台获取任务 BGTaskScheduler shared register forTaskWithIdentifier Backgroun
  • 如何去掉 UIWebView 上的状态栏背景?

    从 iOS 11 开始 当UIWebView全屏时 状态栏上会出现与屏幕颜色相同的假背景UIWebView背景 有人知道如何摆脱它吗 甚至添加IUWebView到故事板并使其全屏将使状态栏背景出现 我一直在尝试编辑 UIWebView 的大
  • Xcode 错误 - 架构 x86_64 的未定义符号?

    我正在运行 Swift 4 和 Xcode 9 beta 我收到此错误 但我不知道如何解决它 我什至不知道这是什么意思 Undefined symbols for architecture x86 64 T0So22AVCapturePho
  • 删除派生数据文件夹后,Xcode 不断重新创建派生数据文件夹

    自动完成功能在 Xcode 6 中不再起作用 我四处搜索 发现删除派生数据文件夹可以解决此问题 每次我删除它时 它都会回来 然后就不会再自动完成了 有什么建议么 Thanks 没关系 我解决了这个问题 我没有声明需要在类内的方法中使用的变量
  • 为 Swift 对象/属性设置观察者

    我一直在寻找一种在连接到 Mac 的显示器数量发生变化时触发方法的方法 我知道我可以获得 NSScreen screens count 的值 但我需要找到一种方法来在该值发生变化时创建通知或其他内容 或者指示所连接的显示器数量发生变化的其他
  • 将自定义图像设置为 UIBarButtonItem 但它不显示任何图像

    我想将自定义图像设置为 UIBarButtonItem 但它只显示周围的矩形框并且不显示实际图像 func setupBrowserToolbar let browser UIToolbar frame CGRect x 0 y 20 wi
  • 以编程方式从底部裁剪图像

    我正在开发自定义相机应用程序 一切进展顺利 但我在从底部裁剪图像时遇到了问题 即 裁剪后的图像与原始图像具有完全相同的宽度 但高度将为原始图像的 1 3 并且必须从底部开始 斯威夫特3解决方案 func cropBottomImage im
  • Xcode 10 Beta 5 — clang:错误:链接器命令失败,退出代码为 1

    有人可以帮我吗 我的项目一切正常 但更新到 Xcode10 Beta5 后 尝试在 iPhone 上运行该应用程序时出现此错误 然而模拟器可以工作 请帮助我 我已经对这个问题进行了网络搜索并发现this https stackoverflo

随机推荐