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?
The closest thing you can get is a struct .
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.
Parameters in C functions There are two ways to pass parameters in C: Pass by Value, Pass by Reference.
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
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With