www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - "Lazy" initialization of structs

reply Daniel Tan Fook Hao <danieltan95 outlook.com> writes:
Somehow this code works for me:

```D
auto error (int status, string description){
     struct Error {
         int status;
         string description;
     }
     Error err = {
         status,
         description
     };
     return err.serializeToJson;
}
```

which is supposed to be the same as

```D
struct Error {
     int status;
     string description;
}
auto error (int status, string description){
     Error err = {
         status,
         description
     };
     return err.serializeToJson;
}
```

If I'm reading this right, in the former, the struct is created 
when the function is called in run-time, and the type is then 
inferred after that? I don't really understand the behavior 
behind this.
Jun 01
next sibling parent Era Scarecrow <rtcvb32 yahoo.com> writes:
On Thursday, 1 June 2017 at 12:04:05 UTC, Daniel Tan Fook Hao 
wrote:
 If I'm reading this right, in the former, the struct is created 
 when the function is called in run-time, and the type is then 
 inferred after that? I don't really understand the behavior 
 behind this.
The only difference between the two, is the inner struct can hold a delegate or a pointer to the function's local variables. If you make the first example 'static struct' then the two are 100% identical (with the exception of visibility of who can see/initiate the struct). Although since there's no function calls from the struct I don't see how it should act any different, though that might not prevent it from throwing the pointer there anyways.
Jun 01
prev sibling next sibling parent Nicholas Wilson <iamthewilsonator hotmail.com> writes:
On Thursday, 1 June 2017 at 12:04:05 UTC, Daniel Tan Fook Hao 
wrote:
 Somehow this code works for me:

 ```D
 auto error (int status, string description){
     struct Error {
         int status;
         string description;
     }
     Error err = {
         status,
         description
     };
     return err.serializeToJson;
 }
 ```

 which is supposed to be the same as

 ```D
 struct Error {
     int status;
     string description;
 }
 auto error (int status, string description){
     Error err = {
         status,
         description
     };
     return err.serializeToJson;
 }
 ```

 If I'm reading this right, in the former, the struct is created 
 when the function is called in run-time, and the type is then 
 inferred after that? I don't really understand the behavior 
 behind this.
They are both functionally equivalent but the Error struct is visible at module scope in the first example, but only visible (nameable) within the function for the second example. The return type of both is whatever `serializeToJson` returns, a Json object. You can also return the struct directly and the same visibly rules apply. In that use the returned type is what is known as a Voldemort type( https://wiki.dlang.org/Voldemort_types).
Jun 01
prev sibling parent Stanislav Blinov <stanislav.blinov gmail.com> writes:
On Thursday, 1 June 2017 at 12:04:05 UTC, Daniel Tan Fook Hao 
wrote:
 Somehow this code works for me:

 ```D
 auto error (int status, string description){
     struct Error {
         int status;
         string description;
     }
     Error err = {
         status,
         description
     };
     return err.serializeToJson;
 }
 ```

 which is supposed to be the same as

 ```D
 struct Error {
     int status;
     string description;
 }
 auto error (int status, string description){
     Error err = {
         status,
         description
     };
     return err.serializeToJson;
 }
 ```
It's not really the same, the structs will have a different type: in the first case, it'd be modulename.error.Error, while in the second case it's just modulename.Error. Furthermore, if Error declared inside the function had methods, it'd become a `nested` struct, which carries a context pointer.
 If I'm reading this right, in the former, the struct is created 
 when the function is called in run-time, and the type is then 
 inferred after that? I don't really understand the behavior 
 behind this.
No, nothing happens at run time, the type is known statically, it is inferred from the `return` statement in that function: https://dlang.org/spec/function.html#auto-functions. If you omit the type or specify 'auto', the compiler will look at your `return`s (if any) and try to infer the type from them. If they clash (i.e. you're trying to return different types from the same function), it's a compile-time error. Otherwise, it's whatever type is being returned.
Jun 01