【问题标题】:Passing auto typed vars to function in D?将自动类型的变量传递给 D 中的函数?
【发布时间】:2010-06-28 15:16:26
【问题描述】:

这在 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 i javascript 相当,但实际上,它是别的东西?

如果它不是动态类型,这可能是另一个主题,是否可以创建一个?或者甚至可能有一个开源库可用?也许是一个 liblazy?

(PS。是的,也许懒惰的开发者就是我:)

【问题讨论】:

  • 谢谢大家!不知道变种!好的,我知道变体对于 D 来说有点“越野”。

标签: dynamic-data d


【解决方案1】:

如果doSomething 是任何类型的ab 的泛型,那么模板版本是正确的做法:

void doSomething(T, U)(T a, U b) {
    // etc.
}

编译器会在编译时检测TU所代表的类型,并生成正确的代码。

【讨论】:

    【解决方案2】:

    我将补充一点,在 std.variant 模块(仅限 D2)中已经实现了与您的运行时类型多态性(var 结构)的想法相近的东西。

    此外,从技术上讲,auto 实际上是一个什么都不做的关键字——它用于您需要没有类型的类型修饰符的地方。如果您不指定类型,D 会从初始化表达式中为您推断出它。例如,所有这些工作:

    auto i = 5;
    const j = 5;
    static k = 5;
    

    【讨论】:

      【解决方案3】:

      停下,不要那样做!我担心如果您在早期忽略类型,将难以掌握它们,特别是因为 D 不是动态类型的。我相信即使在动态语言中类型也很重要。

      您可以使用std.variant 忽略 D2 中的类型,它可以使代码看起来像语言是动态类型的。

      您对模板的使用是正确的,但不是自动的。 D 允许您在许多情况下使用这个词,例如返回类型,因为 D 有一个非常好的推断类型的系统。参数是不带有用于推断类型的重复信息的东西。

      关于 std.variant 的附加信息: 仔细研究一下,这仍然比您想要的要复杂。例如,将值分配给类型化变量需要方法调用。并且您无法从引用中访问类方法。

      int b = a.get!(int);
      a.goFish() // Error Variant type doesn't have goFish method
      

      【讨论】:

        【解决方案4】:

        也许我的困惑源于我认为 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;
        }
        

        编译器能否自动推断abreturn值的类型?没有。除了与 add 运算符一起使用的原语(intbytedouble 等)之外,用户定义的类型可以重载它,等等。因为编译器不能明确地推断出这些类型中的任何一个,所以这是一个错误。类型必须在参数中指定,因为通常不能推断它们(例如,与声明不同)。

        【讨论】:

          猜你喜欢
          • 2017-04-15
          • 2014-04-03
          • 1970-01-01
          • 2016-09-09
          • 2022-01-26
          • 2016-01-15
          • 1970-01-01
          • 1970-01-01
          • 2021-09-14
          相关资源
          最近更新 更多