15

They seem to be the same:

package main

import "fmt"

type S struct {
    i int
}

func main() {
  var s1 *S = new(S)
  fmt.Println(s1)

  var s2 *S = &S{}
  fmt.Println(s2)  // Prints the same thing.
}

Update:

Hm. I just realized that there's no obvious way to initialize S.i using new. Is there a way to do that? new(S{i:1}) does not seem to work :/

allyourcode
  • 21,871
  • 18
  • 78
  • 106

3 Answers3

13

From Effective Go:

As a limiting case, if a composite literal contains no fields at all, it creates a zero value for the type. The expressions new(File) and &File{} are equivalent.

blackgreen
  • 34,072
  • 23
  • 111
  • 129
Woot4Moo
  • 23,987
  • 16
  • 94
  • 151
  • Is there a way to initialize fields using new? – allyourcode Aug 24 '13 at 17:11
  • @allyourcode don't think so. http://stackoverflow.com/questions/4498998/how-to-initialize-members-in-go-struct – Woot4Moo Aug 24 '13 at 17:13
  • Does the documentation say then, why they have chosen to include the `new` function? I thought `go` was all about non overlapping functionality.. – Thomas Ahle Jun 28 '14 at 21:34
  • 2
    @ThomasAhle What about `x := 5` versus `var x = 5` versus `var x int = 5` versus `var x int; x = 5`? It has no shortage of overlapping and redundant ways to do the same thing, though a case can be made in many cases for providing a rich set of idioms to express the programmer's intention as accurately as possible. – Ionoclast Brigham Aug 13 '14 at 23:20
  • I'm not sure whether Effective Go is [*normative*](https://stackoverflow.com/a/6422238/4108803), however the language specifications are less straightforward with respect to `new` vs `& {}` – blackgreen Oct 31 '21 at 11:37
2

Not only do they give the same resulting value, but if we allocate something both ways and look at their values...

// Adapted from http://tour.golang.org/#30
package main

import "fmt"

type Vertex struct {
    X, Y int
}

func main() {
    v := &Vertex{}
    v2 := new(Vertex)
    fmt.Printf("%p %p", v, v2)
}

...we'll see that they are in fact allocated in consecutive memory slots. Typical output: 0x10328100 0x10328108. I'm not sure if this is an implementation detail or part of the specification, but it does demonstrate that they're both being allocated from the same pool.

Play around with the code here.

As for initializing with new, according to the language spec: The built-in function new takes a type T and returns a value of type *T. The memory [pointed to] is initialized as described in the section on initial values. Because functions in go can't be overloaded, and this isn't a variadic function, there's no way to pass in any initialization data. Instead, go will initialize it with whatever version of 0 makes sense for the type and any member fields, as appropriate.

Ionoclast Brigham
  • 1,703
  • 1
  • 12
  • 19
0
Case 1: package main

import (
    "fmt"
)

type Drink struct {
    Name    string
    Flavour string
}

func main() {
    a := new(Drink)
    a.Name = "Maaza"
    a.Flavour = "Mango"
    b := a
    fmt.Println(&a)
    fmt.Println(&b)
    b.Name = "Frooti"

    fmt.Println(a.Name)

}//This will output Frooti for a.Name, even though the addresses for a and b are different.

Case 2:
package main

import (
    "fmt"
)

type Drink struct {
    Name    string
    Flavour string
}

func main() {
    a := Drink{
        Name:    "Maaza",
        Flavour: "Mango",
    }

    b := a
    fmt.Println(&a)
    fmt.Println(&b)
    b.Name = "Froti"

    fmt.Println(a.Name)

}//This will output Maaza for a.Name. To get Frooti in this case assign b:=&a.
Vi137
  • 248
  • 2
  • 10