gpt4 book ai didi

c++ - 从 Swift 中的泛型参数继承的替代方法

转载 作者:行者123 更新时间:2023-11-28 06:23:40 25 4
gpt4 key购买 nike

我是 Swift 的新手,最近注意到您不能从 Swift 中的泛型继承,例如

class MyClass<T> : T {}

在 Swift 3 中无效(参见问题 this question)。

这是我希望用上述构造解决的问题:

protocol Backend {
func operationA(operand: Int)
}

class ConcreteBackend : Backend {

func operationA(operand: Int) {
// ...
}

// Some other functions and/or custom initializers
// ...
}

class EnhancedBackend<T : Backend> : T {

override func operationA(operand: Int) {
// do something smart here
super.operationA(operand: modifiedOperand)
}
}

基本上 EnhancedBackendoperationA 的输入做了一些聪明的事情,然后将它传递给 Backend 的实际实现。我在这里使用继承而不是组合,因为 ConcreteBackend 可能有一些我想要在协议(protocol)中未指定的公共(public)属性、函数和初始化器(因为它们只与具体实现相关)还公开了 EnhancedBackend。如果没有继承,这是不可能的。

C++ 实现可能看起来像

// Using concepts here instead of protocols
class ConrecteBackend {
public:
void operationA(int operand) { .... }
}

template<class T>
class EnhancedBackend : public T {
using Base = T;
public:
// Ensure T is a model of the Backend concept
static_assert(isModelOfConceptBackend<T>::value,
"Template parameter is not a model of concept Backend");

// Ensure all constructors of Base can be used
template<class ...Args, typename = std::enable_if_t<
std::is_constructible<Base, Args...>::value>>
inline EnhancedBackend(Args &&...args) : Base(std::forward<Args>(args)...) {}

void operationA(int operand) {
// ...
Base::operationA(operand);
}
};

所以用C++解决这个问题就很简单了。但目前我不知道如何使用(纯)Swift 3 来实现。

最佳答案

Swift 的泛型与 C++ 模板不同,C++ 模板比 Swift 的类型语义更接近于预处理宏。

然而,有许多方法可以达到类似的效果。如果使用变量来引用需要自定义调度规则的函数,一种方法是:

例如:

protocol Backend:class
{
var operationA:(Int) -> () { get set }

func performOperationA(_ : Int) -> ()
}

class ConcreteBackend : Backend
{
lazy var operationA:(Int) -> () = self.performOperationA

func performOperationA(_ : Int) -> ()
{
// ...
}

// Some other functions and/or custom initializers
// ...
}

extension Backend
{
var enhancedForTesting:Self
{
operationA = testing_OperationA
return self
}

func testing_OperationA(_ operand:Int) -> ()
{
let modifiedOperand = operand + 1
performOperationA(modifiedOperand)
}

}

let enhancedBackend = ConcreteBackend().enhancedForTesting

通过使用变量来引用函数的实现,可以在运行时针对特定实例动态更改 operationA 的行为。

在此示例中,增强功能被添加到后端协议(protocol),但它们也可以由独立函数或什至另一个具有其自身特定类型的更改行为的类设置。

当使用这种方法时,实例具有具体类的所有属性和功能,同时为协议(protocol)的更改功能实现增强的行为。

创建增强实例使用的语法与通用类构造函数一样简单(如果不是更简单的话):

// for example:

let instance = ConcreteBackend(...).enhanced

// rather than:

let instance = EnhancedBackend<ConcreteBackEnd>(...)

关于c++ - 从 Swift 中的泛型参数继承的替代方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42620952/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com