Types 虚拟静态值类型

Types 虚拟静态值类型,types,d,Types,D,是否可以为编译时类型安全和函数重载创建“虚拟”值类型 例如,一个greet函数总是接受一个字符串,但基于生成该字符串的方法,它将调用正确的变量 我想这样做是为了简化库的API。 例如,我没有使用greetByFirstName和greetByLastName,而是使用了一个greet方法,如下所示: import std.array; import std.format; import std.stdio; string firstName(string name) { return

是否可以为编译时类型安全和函数重载创建“虚拟”值类型

例如,一个greet函数总是接受一个字符串,但基于生成该字符串的方法,它将调用正确的变量

我想这样做是为了简化库的API。 例如,我没有使用greetByFirstName和greetByLastName,而是使用了一个greet方法,如下所示:

import std.array;
import std.format;
import std.stdio;

string firstName(string name) {
    return name.split(" ")[0];
}

string lastName(string name) {
    return name.split(" ")[1];
}

string greet(FirstName name) {
    return "Hi %s!".format(name);
}

string greet(LastName name) {
    return "Hello Mr. %s!".format(name);
}

unittest {
    string name = "John Smith";
    assert(firstName(name) == "John");
    assert(firstName(name).greet() == "Hi John!");
    assert(lastName(name).greet() == "Hello Mr. Smith!");
}

void main() {}

您可以创建一个新类型,将此别名为基类型,然后在更具体的类型上重载。别名这可以看作是一种使用结构进行继承的方法,隐式转换回基本“接口”类型

现在,代码的其余部分将根据需要工作,您仍然可以在需要时将FirstName和LastName视为字符串

 // these are the new types
struct FirstName { 
    string name; 
    alias name this; // this allows implicit conversion back to string when needed
} 
struct LastName { 
    string name; 
    alias name this; 
} 
FirstName firstName(string name) {  // these return the more specific  type
    return FirstName(name.split(" ")[0]); 
} 
LastName lastName(string name) { 
    return LastName(name.split(" ")[1]); 
}