# Set Id of struct on construction

**URL:** https://discourse.julialang.org/t/set-id-of-struct-on-construction/48977
**Category:** General Usage
**Created:** [October 25, 2020, 1:35pm UTC](https://discourse.julialang.org/t/set-id-of-struct-on-construction/48977 "2020-10-25T13:35:27Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![cojua8](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cojua8/32/11882_2.png) [@cojua8](https://discourse.julialang.org/u/cojua8)
#### Post date: [October 25, 2020, 1:35pm UTC](https://discourse.julialang.org/t/set-id-of-struct-on-construction/48977/1 "2020-10-25T13:35:27Z")

</div>

Hi,

I’m trying to implement a struct that must have an Id, which is set on construction, similar to C# static member

So far, I have been able to do it like this:

```julia
x = 0

struct A
    prop1
    id
    A(prop1) = begin
        global x+=1
        new(prop1, x)
    end
end

```

But I think there should be a better way.

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [October 25, 2020, 3:18pm UTC](https://discourse.julialang.org/t/set-id-of-struct-on-construction/48977/2 "2020-10-25T15:18:31Z")

</div>

Maybe a closure like

```julia
let x::Int = 0
    struct Foo
        x::Int
        function Foo()
            x += 1
            new(x)
        end
    end
end

```

(note: not thread safe in this form).

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [October 25, 2020, 3:43pm UTC](https://discourse.julialang.org/t/set-id-of-struct-on-construction/48977/3 "2020-10-25T15:43:26Z")

</div>

Building an array of structs would not suffice, with the generation of new instances done using `push!` to that array? I do not know if that can be adapted to your problem, but seem much safer than updating a global variable.

If that is not good, I do not see much escaping from what you have done. Except that I perhaps would use a counter that is constant with mutable fields, to avoid messing up with other variables:

```julia
julia> struct A
          id
          x
       end

julia> function Generate_A_and_Count!( x, counter )
         counter[1] +=1 
         A(counter[1],x)
       end
Generate_A_and_Count (generic function with 1 method)

julia> const A_counter = [0]

julia> A(x) = Generate_A_and_Count!(x,A_counter)
A

julia> A(1.)
A(1, 1.0)

julia> A(1.)
A(2, 1.0)

```

---

<div class="post-metadata">

### Author: ![zekeriya.sari](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zekeriya.sari/32/13695_2.png) [@zekeriya.sari](https://discourse.julialang.org/u/zekeriya.sari)
#### Post date: [October 25, 2020, 4:00pm UTC](https://discourse.julialang.org/t/set-id-of-struct-on-construction/48977/4 "2020-10-25T16:00:33Z")

</div>

Maybe you can assign a UUID to your struct. Something like

```julia
julia> using UUIDs

julia> struct Mytype{T}
           prop1::T 
           id::UUID
           Mytype(prop1::T) where T = new{T}(prop1, uuid4())
       end 

julia> obj = Mytype(1.) 
Mytype{Float64}(1.0, UUID("9bc25060-6548-44ff-9422-52d63fe77ed7"))

```

But, now I realized that `id` here is not the total count of the instances of `Mytype` 🙂 I do not know, this approach may still be useful, though.

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [October 25, 2020, 4:05pm UTC](https://discourse.julialang.org/t/set-id-of-struct-on-construction/48977/5 "2020-10-25T16:05:49Z")

</div>

> [@Tamas\_Papp](#):
>
> ```julia
> let x::Int = 0
> struct Foo
> x::Int
> function Foo()
> x += 1
> new(x)
> end
> end
> end
> 
> ```

This is interesting, but I do not understand it. How come the value of `x` is visible and updated among successive calls of `Foo()`? In what scope is `x`?

---

<div class="post-metadata">

### Author: ![WschW](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wschw/32/6575_2.png) [@WschW](https://discourse.julialang.org/u/WschW)
#### Post date: [October 25, 2020, 4:10pm UTC](https://discourse.julialang.org/t/set-id-of-struct-on-construction/48977/6 "2020-10-25T16:10:42Z")

</div>

`x` exists in the scope of the `let` block and in the scope of any function defined within that block that close over the variable of `x`.

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [October 25, 2020, 4:20pm UTC](https://discourse.julialang.org/t/set-id-of-struct-on-construction/48977/7 "2020-10-25T16:20:56Z")

</div>

Probably I should be starting a new thread, but why in the example below `A()` is available in the global scope, but `f()` is not?

```julia
julia> let 
         struct A
           x
         end
         A() = A(1)
       end
A

julia> A()
A(1)

julia> let 
         f() = 1
       end
(::var"#f#1") (generic function with 1 method)

julia> f()
ERROR: UndefVarError: f not defined

```

Given that, are `let` blocks a reasonable choice to define functions (objective functions for optimization solvers, for example), with parameters? Something like:

```julia
julia> let 
         struct f end
         a = 1
         f(x) = (x-a)^2
       end

julia> f(3)
4

```

Here `f` is a constructor of the type `f` (needed for `f` to be available in the global scope), and `a` is a constant parameter of the function. Using a struct like that seems ugly, but would that work?

---

<div class="post-metadata">

### Author: ![WschW](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wschw/32/6575_2.png) [@WschW](https://discourse.julialang.org/u/WschW)
#### Post date: [October 25, 2020, 4:31pm UTC](https://discourse.julialang.org/t/set-id-of-struct-on-construction/48977/8 "2020-10-25T16:31:22Z")

</div>

Let blocks create a local scope. Within local scopes when functions are defined Julia makes them local to that scope unless instructed to do otherwise.

For example:

```julia
let 
  global f() = 1
end

```

will be callable outside of the let block.

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [October 26, 2020, 9:10am UTC](https://discourse.julialang.org/t/set-id-of-struct-on-construction/48977/9 "2020-10-26T09:10:16Z")

</div>

> [@lmiq](#):
>
> This is interesting, but I do not understand it

[https://docs.julialang.org/en/v1/manual/variables-and-scoping/#Let-Blocks](https://docs.julialang.org/en/v1/manual/variables-and-scoping/#Let-Blocks)

> [@lmiq](#):
>
> why in the example below `A()` is available in the global scope, but `f()` is not?

Composite type names (`struct`, `mutable struct`) end up in global scope. (The scope chapter could clarify this a bit more IMO).

---

<div class="post-metadata">

### Author: ![cojua8](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cojua8/32/11882_2.png) [@cojua8](https://discourse.julialang.org/u/cojua8)
#### Post date: [October 26, 2020, 3:44pm UTC](https://discourse.julialang.org/t/set-id-of-struct-on-construction/48977/10 "2020-10-26T15:44:19Z")

</div>

Thank you!, I liked the uuid and let approaches, they are very useful solutions for different use cases.
