# What's the difference between \`self: MyType\` and \`self: \*MyType\`?

**URL:** <https://ziggit.dev/t/whats-the-difference-between-self-mytype-and-self-mytype/2590>\
**Category:** Help\
**Tags:** language\
**Created:** [December 25, 2023, 2:26pm UTC](https://ziggit.dev/t/whats-the-difference-between-self-mytype-and-self-mytype/2590 "2023-12-25T14:26:44Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![tison](https://ziggit.dev/user_avatar/ziggit.dev/tison/32/1219_2.png) [@tison](https://ziggit.dev/u/tison)\
**Post date:** [December 25, 2023, 2:26pm UTC](https://ziggit.dev/t/whats-the-difference-between-self-mytype-and-self-mytype/2590/1 "2023-12-25T14:26:44Z")

</div>

```zig
pub const MyType = struct {
  pub fn f(self: MyType) !void {
  }
  pub fn g(self: *MyType) !void {
  }
}

```

It seems both method can be called with `myTypeInstance.method()`. Zig should not have implicit copy consturtion. So what is the difference?

---

<div class="post-metadata">

**Author:** ![tensorush](https://ziggit.dev/letter_avatar_proxy/v4/letter/t/6a8cbe/32.png) [@tensorush](https://ziggit.dev/u/tensorush)\
**Post date:** [December 25, 2023, 2:43pm UTC](https://ziggit.dev/t/whats-the-difference-between-self-mytype-and-self-mytype/2590/2 "2023-12-25T14:43:30Z")

</div>

Hi! The difference is that in the case of `my_type_instance.f()` the compiler passes the instance either by value or by constant reference depending on what it thinks would be best, but either way you won’t be able to mutate the instance inside the function. In the case of `my_type_instance.g()`, you’re telling the compiler to pass the instance by pointer and allow you to mutate the instance behind that pointer.

There’s a 3rd alternative: `fn h(self: *const MyType) void {}` which is a kind of combination of the first two because this forces the compiler to pass the instance by pointer, but you won’t be able to mutate that instance.

---

<div class="post-metadata">

**Author:** ![tison](https://ziggit.dev/user_avatar/ziggit.dev/tison/32/1219_2.png) [@tison](https://ziggit.dev/u/tison)\
**Post date:** [December 25, 2023, 4:25pm UTC](https://ziggit.dev/t/whats-the-difference-between-self-mytype-and-self-mytype/2590/3 "2023-12-25T16:25:58Z")

</div>

Thank you! But what does it mean for passing by value? IIUC Zig doesn’t have implicit copy construction. So if my struct is complex or even allocated, how does it get pass by value?

Well, since the param is immutable, it’s fine a programmer doesn’t find the difference. Passing by value should mean a shallow copy.

---

<div class="post-metadata">

**Author:** ![tensorush](https://ziggit.dev/letter_avatar_proxy/v4/letter/t/6a8cbe/32.png) [@tensorush](https://ziggit.dev/u/tensorush)\
**Post date:** [December 25, 2023, 5:07pm UTC](https://ziggit.dev/t/whats-the-difference-between-self-mytype-and-self-mytype/2590/4 "2023-12-25T17:07:06Z")

</div>

Yeah, so for instance in the trivial case when it’s a big constant struct, which you’re never mutating, the compiler would pass by constant reference, trying to avoid an expensive copy. Cases when you have a variable that you’re mutating elsewhere, the compiler will create a copy. That’s why it’s better to pass big and/or heap-allocated things by pointers. At least that’s the way I understand it.

---

<div class="post-metadata">

**Author:** ![Cloudef](https://ziggit.dev/user_avatar/ziggit.dev/cloudef/32/1370_2.png) [@Cloudef](https://ziggit.dev/u/Cloudef)\
**Post date:** [December 27, 2023, 2:59pm UTC](https://ziggit.dev/t/whats-the-difference-between-self-mytype-and-self-mytype/2590/5 "2023-12-27T14:59:22Z")

</div>

There is interesting footgun related to this [Footgun: hidden pass-by-reference · Issue #5973 · ziglang/zig · GitHub](https://github.com/ziglang/zig/issues/5973#issuecomment-1330743975)
