Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Equivalent of C# `readonly` keyword in D?

Tags:

c#

immutability

d

From what I understand while reading up on D, when using the immutable keyword on a variable, the value of the variable must be known at compile time, while C#'s readonly need not be, and readonly fields can be assigned in a class constructor using non-static values. Is this possible in D?

like image 363
Mark LeMoine Avatar asked May 17 '11 20:05

Mark LeMoine


People also ask

What is equivalent to classes in C?

The closest thing you can get is a struct .

Are there templates C?

The main type of templates that can be implemented in C are static templates. Static templates are created at compile time and do not perform runtime checks on sizes, because they shift that responsibility to the compiler.

Is there pass in C?

Parameters in C functions There are two ways to pass parameters in C: Pass by Value, Pass by Reference.


2 Answers

In D2, const member can only be initialized inside the constructor (or directly in the class declaration, but not both):

import io = std.stdio;

class A
{
    const int member;
    this(int nb)
    {
        this.member = nb;
    }
}

void main()
{
    A a = new A(12);
    io.writeln(a.member);
    //a.member = 14; //Error: can only initialize const member member inside constructor
}
like image 142
Raphaël Londeix Avatar answered Sep 22 '22 14:09

Raphaël Londeix


As there appears to be some confusion (from both the original question, and he_the_great's comment) regarding immutable, I thought I'd add an aside.

When you say immutable int i = 42, you are saying that i will not be modified, not that it the value is known at compile time. immutable is actually a type modifier, and creates a new type. immutable T is a short-hand for immutable(T). immutable(T) creates a T that can never be mutated, that is, if you read the value, then call a function, the value will be the same. Compare this to const(T) which provides the weaker guarantee that this instance of the type will not be modified, but someone may have mutable access to it else where, so if you read the value and then call a function, you cannot assume the value will be the same.

In general, immutable(T) != T. However there are certain situations where they are implicitly convertible to one another. If T is a type that is said to have no "mutable indirection", for instance. That is to say, if I pass a function an immutable(int), they receive a copy -- there is no way that that function can modify the value I passed, as it is copied -- if the type system didn't allow that, it would just be annoying with no added guarantees, so the D type system allows it. However, if I pass an immutable(int*), that can be changed by the calling function. In the case of structs, if any member has mutable indirection then the struct is said to have it as well.

So to turn away from theory and back to more practical matters, it's not true at all that immutable values have to be known at compile time, and that there's no good way to create them. However, the only mutation can occur inside the constructor. For simple scalar types, this is pretty obvious:

immutable(int) i = rand();

But what about something like an object? Well, to construct a type T we use

auto t = new T();

so to construct the type immutable(T) we use

auto t = new immutable(T)();

here's a more complete little example

class Useless
{
    int i;

    this(int i)
    {
        this.i = i;
    }
}

int main(string[] args)
{
    auto o = new immutable(Useless)(cast(int) args.length);
    //o.i = 17;  error
    return o.i;  // fine
}

As you can see, mutation can occur inside the constructor. You can read member variables, but cannot write them (immutable is transitive; that is, every member (and every member of members) becomes immutable if the parent does. You can only call methods if they're marked as const.

I apologise for the off-topic rambling, but I see that a lot of people appear to be confused regarding this topic.

like image 28
Bernard Avatar answered Sep 19 '22 14:09

Bernard