子类结构或类似

Subclass a Struct or Similar

我了解结构和 类(以及协议)在基本层面上的工作原理。我有一个相当普遍的情况:

我需要具有运算符的泛型值类型,这些运算符确实必须在赋值时进行复制。 这些类型具有复杂的结构,我希望能够通过子类化来专门化,否则到处都是复制代码,这将是糟糕的编程。

我已经尝试过协议和扩展,但是因为协议不是通用的,所以我无法定义我想要的(通用)运算符。 如果我使用 类 我将不会在分配时复制。

今天的例子是我有Matrix,在那个下面有SquareMatrix,有特定的方阵函数。有运算符,矩阵可以由任何符合我的环协议的东西填充。我尝试在具有关联类型和扩展的协议中定义几乎所有功能。

编辑:我真的很想知道我应该编码什么。在矩阵情况下,我需要能够像其他任何方阵一样传递方阵,所以子类化是唯一的选择吗?也许我错了。主要问题是当我必须编写一个讨论内部值的函数时,我必须知道泛型类型参数才能做任何有用的事情。例如,在定义加法时,我必须创建一个新矩阵并声明它的泛型类型,但是当我只知道某物是一个(非泛型)协议时,我从哪里得到它——它的真实类型是泛型的,但尽管协议有这个关联类型,我没有办法把它弄出来。

解决方案 感谢 alexander momchliov。本质上需要做更多的工作才能将代码完全移动到协议扩展中并为所有相关类型使用 'Self'。在扩展中,编译器对泛型类型很满意。

代码是私人的,很抱歉我无法在这个问题中粘贴任何代码。感谢您的耐心等待和帮助。

结构 inheritance/polymorphism 至少有两个原因(我能想到)是不可能的。

  1. 结构是按值存储和移动的。这要求编译器在编译时知道结构的确切大小,以便知道在结构实例开始后要复制多少字节。

    假设有一个结构A,和一个继承自A的结构B。每当编译器看到 A 类型的变量时,它无法确定运行时类型是否真的是 A,或者是否使用了 B。如果 B 添加了 A 没有的新存储属性,那么 B 的大小将不同于(大于)A。编译器将无法确定运行时类型和这些结构的大小。

  2. 多态性需要函数 table。函数 table 将存储为结构类型的静态成员。但是要访问这个静态成员,每个结构实例都需要一个对实例类型进行编码的实例成员。这通常称为“isa”指针(例如,此实例 A 类型)。对于每个实例,这将是 8 个字节的开销(在 64 位系统上)。考虑到 IntBoolDouble 和许多其他常见类型都是作为结构实现的,这将是 unacceptable 的开销。试想一下,Bool 是一个字节值,需要 8 个字节的开销。那是 11% 的效率!

由于这些原因,协议在 Swift 中发挥了重要作用,因为它们允许您引入类似继承的行为,而没有这些问题。

首先,在 swift 中,如果您要使用 associatedtype,协议可以是通用的。

另一方面,您需要值语义,因此您可以使用 Copy on Write 方法。这将为您的 类 赋予值语义(因此它们将与结构一样安全)。

这两种方法都可以解决你的问题。