Self类型的存储变量(尤其是在子类化时)

编程入门 行业动态 更新时间:2024-10-26 04:20:49
本文介绍了Self类型的存储变量(尤其是在子类化时)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 class LinkedNode<T> { var value: T var next: Self? required init(_ value: T) { self.value = value } } class DoublyNode<T>: LinkedNode<T> { weak var previous: DoublyNode? override var next: Self? { didSet { next.previous = self } } }

我希望它能像这样编译.但事实并非如此.

I wish it compiles like this. But it doesn't.

存储的属性不能具有协变"Self"类型

Stored property cannot have covariant 'Self' type

我必须重写代码以使其能够编译和工作:

I have to rewrite the code to make it compile and work:

class LinkedNode<T> { var value: T var next: LinkedNode? required init(_ value: T) { self.value = value } } class DoublyNode<T>: LinkedNode<T> { weak var previous: DoublyNode? override var next: LinkedNode<T>? { didSet { (next as! Self).previous = self } } }

在每次引用next属性之后,在以后的代码中的每个地方,我都必须手动将其强制转换为DoublyNode(当我使用DoublyNode时),因为它始终具有LinkedNode类型. 这是可管理的,但令人讨厌又丑陋.

And everywhere in the later code every time after referring to next property I have to manually cast it to DoublyNode (when I'm working with DoublyNode) because it always has type LinkedNode. It's manageable but annoying and ugly.

推荐答案

让我演示一下Swift为什么不允许这样做的原因.如果确实允许您像这样使用Self,则理论上您可以这样做:

Let me demonstrate why Swift disallows this. If it did allow you to use Self like that, you could in theory do:

let doublyNode = DoublyNode(1) let linkedNode: LinkedNode<Int> = doublyNode // this assignment should work, right? linkedNode.next = LinkedNode(2) // "linkedNode" is of type LinkedNode, so Self is LinkedNode, so I can do this assignment, right?

现在会发生什么? DoublyNode中next的didSet被调用,并尝试访问LinkedNode(2)的previous.问题是,LinkedNode甚至没有previous属性!因此,允许您以这种方式使用Self是不安全的.

Now what happens? The didSet of next in DoublyNode gets called, and it tries to access previous of LinkedNode(2). The thing is, LinkedNode doesn't even have a previous property! Therefore, allowing you to use Self this way is unsafe.

我认为DoublyNode根本不应该继承LinkedNode.亚历山大的回答很好地说明了这一点,即违反了 LSP .将这两个类关联起来可以做的一件事就是使用协议:

I don't think DoublyNode should inherit from LinkedNode at all. Alexander's answer explains this very well, namely that this violates the LSP. One thing you could do to relate these two classes, is with a protocol:

protocol LinkedNodeProtocol { associatedtype Data var value: Data { get set } var next: Self? { get set } init(_ value: Data) } final class LinkedNode<Data>: LinkedNodeProtocol { var value: Data var next: LinkedNode? init(_ value: Data) { self.value = value } } final class DoublyNode<Data>: LinkedNodeProtocol { var value: Data weak var previous: DoublyNode? var next: DoublyNode? { didSet { next?.previous = self } } init(_ value: Data) { self.value = value } }

更多推荐

Self类型的存储变量(尤其是在子类化时)

本文发布于:2023-06-06 10:49:22,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/539029.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:是在   子类   变量   类型

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!