天天看點

d子產品實作多态

​​原文​​​ 我想到了兩種可能性.一個是使用​

​UFCS​

​,定義​

​類型​

​作為​

​第一個參數​

​的​

​其他子產品​

​中​

​命名​

​函數(它不适合操作符重載),然後可用​

​點文法​

​調用:

module myvector;
struct vector {
     float x;
     float y;
}
//
module myvectormath;
import myvector;
vector add(vector lhs, vector rhs) {
     // 内部是普通函數.
     vector result;
     result.x = lhs.x + rhs.x;
     result.y = lhs.y + rhs.y;
     return result;
}      

用法:

import myvector;
import myvectormath;

// 可用.号來調用
vector a = vector(0,0).add(vector(5, 5));      

另一種可能的方法是把​

​資料​

​​放入​

​結構或插件模闆​

​​中,然後通過放其入具有​

​所需​

​​功能的另一個​

​結構​

​​中來計算​

​數學​

​:

// 資料
module myvector;

// 外部命名類型,
struct VectorData {
   float x;
   float y;
}

// 準備
mixin template vector_payload() {
// 構造器,友善初化
this(float x, float y) {
    _data.x = x;
    _data.y = y;
}
this(VectorData d) {
    _data = d;
}

    // 存儲資料
VectorData _data;
alias _data this;//隐式轉換.
}

// 數學#1子產品
module myvectormath;
import myvector;

struct vector {
    // 插件資料
    mixin vector_payload!();

// 加方法,重載操作符
    vector opBinary(string op:"+")(vector rhs) {
        vector result;
        result.x = this.x + rhs.x;
        result.y = this.y + rhs.y;
        return result;
    }
}

// #2子產品
module myvectormath2;
import myvector;

struct vector {
    // 插件
    mixin vector_payload!();

// 加方法
    vector opBinary(string op:"+")(vector rhs) {
        vector result;
    // 完全不一樣
        result.x = this.x - rhs.x;
        result.y = this.y - rhs.y;
        return result;
    }
}

// 用法 
import myvectormath;
// 或
//import myvectormath2;
void main() {
    vector a = vector(0, 0) + vector(5, 5);
    import std.stdio;
    writeln(a);
}      

如何同時使用?這就是内部結構​

​_Data​

​​,構造器和别名的​

​用武​

​​之地.

是以,首先,要消除​​

​名字​

​​歧義.現在,隻使用​

​全名​

​.

// 用法
import myvectormath;
import myvectormath2;
void main() {
    // 指定類型
    myvectormath.vector a = myvectormath.vector(0, 0) + myvectormath.vector(5, 5);
    import std.stdio;
    writeln(a); // 正确
}      

怎樣才能輕松地在​

​内部​

​​移動它們?建立使用​

​#2​

​版本的函數:

void somethingWithMath2(myvectormath2.vector vec) {
// ...
}      

如果傳遞​

​"a"​

​​變量給它,它會抱怨,因為它是​

​myvectormath.vector​

​​,而這是​

​myvectormath2​

​​.

但是,可很容易地轉換它們,這要歸功于​​

​mixin​

​​模闆中的外部資料結構,​

​ctor​

​和别名:

somethingWithMath2(myvectormath2.vector(a));      
import myvector;
void somethingWithMath2(VectorData a_in) {
// 運算
auto a = myvectormath2.vector(a_in);
// 使用
}
//調用
somethingWithMath2(a);