这在D:
中不起作用void doSomething(auto a, auto b){
// ...
}
我只是好奇,这会不会有用?或者这在技术上是不可能的? (或者只是简单的愚蠢?)
无论如何,这可以通过其他任何方式完成吗?我想我可以使用...
并查看参数列表,但我有点为懒惰的新手制作一个库,并希望他们能够轻松地创建函数而无需真正关心数据类型。我正在尝试创建一个名为var
的结构,如
struct var{
byte type;
void* data
// ...
}
// and overload like all operators so that a lazy devver can do
var doSomething(var a, var b){
if(a == "hello")
b = 8;
var c = "No.:" ~ b ~ " says:" ~ a;
return c;
}
但是我的脑袋已经开始受伤了。而且,我有点觉得我错过了什么。我也痛苦地意识到这可能是模板的用途......是吗?从我知道的一点点来看,模板看起来像这样(?)
void doSomething(T, U)( T a, U b){
// ...
}
但现在它看起来不那么干净了。也许我已经倒退了所有这些。也许我的困惑源于我相信auto
是一种动态类型,与var
我的javascript相当,但实际上,它还有其他的东西?
如果它不是动态类型,这可能是另一个主题,是否可以创建一个?或者甚至可能有一个开源库?一个liblazy可能吗?
(PS。是的,也许懒惰的人是我:)
答案 0 :(得分:12)
如果doSomething
对任何类型的a
和b
都是通用的,那么模板版本是正确的:
void doSomething(T, U)(T a, U b) {
// etc.
}
编译器将在编译时检测T
和U
表示的类型,并生成正确的代码。
答案 1 :(得分:6)
我只想补充一点,关于运行时类型多态性(var
结构)的概念已经在std.variant模块中实现(仅限D2)。
另外,从技术上讲,auto
实际上是一个什么都不做的关键字 - 它用于需要没有类型的类型修饰符的地方。如果您没有指定类型,D将从初始化表达式中为您推断出它。例如,所有这些工作:
auto i = 5;
const j = 5;
static k = 5;
答案 2 :(得分:2)
停止,不要那样做!我担心如果你在早期忽略类型就很难掌握它们,特别是因为D不是动态类型的。我相信即使在动态语言中类型也很重要。
您可以使用std.variant忽略D2中的类型,它可以使代码看起来像是动态输入的语言。
您对模板的使用是正确的,但不是自动的。 D允许您在许多情况下使用此单词,例如返回类型,因为D有一个非常好的系统来推断类型。参数是不具有要推断的类型的重复信息的东西。
有关std.variant的其他信息: 再看一下,这比你想要的更复杂。例如,要将值分配给类型变量,需要进行方法调用。并且您无法从引用中访问类方法。
int b = a.get!(int);
a.goFish() // Error Variant type doesn't have goFish method
答案 3 :(得分:1)
也许我的困惑源于我相信auto是一种动态类型,可与var i javascript相媲美,但实际上,它还有其他的东西?
auto
是storage class。实际上,它是默认的存储类;它并不意味着“这有一个存储类”之外的任何东西。
现在如果编译器可以明确地推断出类型,那么一切都很好。否则,这是一个错误:
auto i = 42; // An integer literal is inferred to be of type 'int'.
auto j; // Error!
所以auto
根本不是一种类型。请记住,这一切都必须在编译时发生,而不是在运行时发生。那么让我们来看一个函数:
auto add(auto a, auto b)
{
return a + b;
}
编译器能否自动推断出a
,b
或return
值的类型?不。除了与添加运算符(int
,byte
,double
等)一起使用的基元之外,用户定义的类型可能会使其超载,依此类推。因为编译器无法明确地推断出任何这些类型,所以这是一个错误。必须在参数中指定类型,因为通常不能推断它们(例如,与声明不同)。