# How to use Ptr/Ref?

**URL:** <https://discourse.julialang.org/t/how-to-use-ptr-ref/6398>\
**Category:** New to Julia\
**Created:** [October 12, 2017, 12:04am UTC](https://discourse.julialang.org/t/how-to-use-ptr-ref/6398 "2017-10-12T00:04:40Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![tuckermcclure](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tuckermcclure/32/1187_2.png) [@tuckermcclure](https://discourse.julialang.org/u/tuckermcclure)\
**Post date:** [October 12, 2017, 12:04am UTC](https://discourse.julialang.org/t/how-to-use-ptr-ref/6398/1 "2017-10-12T00:04:40Z")

</div>

Suppose I have some big struct and I also have some big dictionary. I want an element in the dictionary to “point to” a field of the struct, such that if I assign to the field of the struct, you’d “see it” by accessing the dictionary, and conversely, if I assign to the element in the dictionary, you’d “see it” in the struct. In C, I’d make the “dictionary” be a pointer to the field, and I could always write to the referenced location. How would this be done cleanly in Julia?

```julia
mutable struct MyStruct
    visible
    hidden
end

# Let's create a bunch of things that have both visible and hidden parts.
s = MyStruct(1, 2)

# Let's make a dictionary of visible things.
d = Dict("entry1" => nothing,
         "entry2" => s.visible)

s.visible = 3
display(d["entry2"]) # I'd like to see 3.

d["entry2"] = 4
display(s.visible) # I'd like to see 4.

```

I could do something cheesy, like make the `visible` field into a vector with 1 element and write to that, but I don’t like that solution at all.

I’m not sure if this actually involves `Ptr` or `Ref` (or `pointer`). I’m just curious what the right approach is here. It seems like a basic thing to do.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [October 12, 2017, 12:40am UTC](https://discourse.julialang.org/t/how-to-use-ptr-ref/6398/2 "2017-10-12T00:40:11Z")

</div>

No you can’t do just that. Assigning to a dict can only have one sideeffect-changing the dict-and nothing else.

You can of course store something that can let you find the field in there e.g. the `MyStruct` itself and just assign to the visible field of that object instead of mutating the Dict. You can also create a wrapper type so that it holds a reference to the `MyStruct` object and `setindex!` (or whatever) on it will mutate the `visible` field.

---

<div class="post-metadata">

**Author:** ![tuckermcclure](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tuckermcclure/32/1187_2.png) [@tuckermcclure](https://discourse.julialang.org/u/tuckermcclure)\
**Post date:** [October 12, 2017, 1:30am UTC](https://discourse.julialang.org/t/how-to-use-ptr-ref/6398/3 "2017-10-12T01:30:43Z")

</div>

I had a feeling that this was a question for @yuyichao! Thanks for answering so fast.

It seems like I can use a `Ref` with the zero-dimensional array “trick” from the Calling C and Fortran documentation to do what I want. I can write to and read from the zero-dimensional with an extra `[]` on the end.

```julia
mutable struct MyStruct{A,B}
    visible::A
    invisible::B
end

s = MyStruct(Ref(1), 2)

d = Dict("entry1" => nothing,
         "entry2" => s.visible)

s.visible[] = 3
display(d["entry2"][]) # Outputs 3

d["entry2"][] = 4
display(s.visible[]) # Outputs 4

```

This is essentially the same as my “make the `visible` field into a vector” suggestion, except that the vector is zero-length. In C, you’d need a de-referencing operator (`*`) to do what I describe, and so we might think of `[]` as a sort of de-referencing operator here, and hence the solution isn’t more difficult than C. It just looks funny, but so do those asterisks in C.

I’m really asking this question because I don’t understand what a `Ref` _is_ or how it’s different from a `Ptr` or a `pointer`, and there’s very little documentation in this area.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [October 12, 2017, 3:20am UTC](https://discourse.julialang.org/t/how-to-use-ptr-ref/6398/4 "2017-10-12T03:20:21Z")

</div>

What I was saying that is you don’t need to do this. Having `s.visible = 3` to affect what you get from `d["entry2"]` is totally fine (though `d["entry2"]` will not be `3`). Just that having `d["entry2"] = 4` to affect `s.visible` is not.

You can just make

```julia
struct ReferenceOfTheVisibleFieldOfMyStruct
    obj::MyStruct
end
Base.getindex(r::ReferenceOfTheVisibleFieldOfMyStruct) = r.visible
Base.setindex!(r::ReferenceOfTheVisibleFieldOfMyStruct, v) = r.visible = v

```

and do

```julia
d["entry2"] = ReferenceOfTheVisibleFieldOfMyStruct(s)

```

instead.

> [@tuckermcclure](#):
>
> I’m really asking this question because I don’t understand what a Ref

Unless you want to convert it to a pointer, it’s just a normal type. There’s nothing special about it which is why there’s no document about it. There’s nothing to document. It is used to represent certain argument convertion in `ccall` / `cfunction` and that’s it. A `Ptr` is, well, a pointer. A `Ref` can usually be converted to a `Ptr` (since their use in `ccall` requires this) using `unsafe_convert` but that’s not something special about them. (It’s just one of the many object that has this property in Base and it is used to represent a specific type of convertion).

You can simply ignore the

> Behaves like a Ptr{T} that can manage its memory via the Julia GC.

In the doc.
