Structs

Examples Filter
package main

import "fmt"

type rect struct {
    width, height int
}

func (r *rect) area() int {
    return r.width * r.height
}

func (r rect) perim() int {
    return 2*r.width + 2*r.height
}

func main() {
    r := rect{width: 10, height: 5}

    fmt.Println("area: ", r.area())
    fmt.Println("perim:", r.perim())

    rp := &r
    fmt.Println("area: ", rp.area())
    fmt.Println("perim:", rp.perim())
}
Go’s structs are typed collections of fields. They’re useful for grouping data together to form records.
package main

import "fmt"

// Define a struct.
type person struct {
    name string
    age  int
}

// This function initializes a struct variable and returns a pointer to it.
func NewPerson(name string) *person {
    p := person{name: name}
    p.age = 42
    return &p
}

func main() {
    // Without keys, you can initialize the members in order that they were defined.
    fmt.Println(person{"Bob", 20})
    
    // With keys.
    fmt.Println(person{name: "Alice", age: 30})

    // Omitted members will be initialized with their "zero value".
    fmt.Println(person{name: "Fred"})

    // Returning a pointer to an initialized struct.
    fmt.Println(&person{name: "Ann", age: 40})

    // Calling a function to create our struct.
    fmt.Println(NewPerson("Jon"))

    // Using the dot operator to access the member values. Works with values and pointers.
    s := person{name: "Sean", age: 50}
    fmt.Println(s.name)

    sp := &s
    fmt.Println(sp.age)

    sp.age = 51
    fmt.Println(sp.age)
}
// V doesn't have classes. But you can define methods on types.
// A method is a function with a special receiver argument.
// The receiver appears in its own argument list between the fn keyword and the method name.
// In this example, the can_register method has a receiver of type User named u.
// The convention is not to use receiver names like self or this, but a short, preferably one letter long, name.
struct User {
	age int
}

fn (u User) can_register() bool {
	return u.age > 16
}

user := User{age: 10}
println(user.can_register()) // "false" 

user2 := User{age: 20}
println(user2.can_register()) // "true"
Last Run  :
false
true
// Struct fields are private and immutable by default (making structs immutable as well).
// Their access modifiers can be changed with pub and mut.
// In total, there are 5 possible options:
struct Foo {
	a int     // private immutable (default)
mut:
	b int     // private mutable
	c int     // (you can list multiple fields with the same access modifier) 
pub:
	d int     // public immmutable (readonly)
pub mut:
	e int     // public, but mutable only in parent module 
__global:
	f int 	  // public and mutable both inside and outside parent module 
}                 // (not recommended to use, that's why the 'global' keyword 
                  // starts with __)
module main

/* STRUCT EXAMPLE 1 */
struct Point {
	x int
	y int
}

fn example1() {
	p := Point{
		x: 10
		y: 20
	}
	println(p.x) // Struct fields are accessed using a dot
}

/* STRUCT EXAMPLE 2 */
fn example2() {
	// Structs are allocated on the stack. To allocate a struct on the heap and get a reference to it, use the & prefix:
	// Alternative initialization syntax for structs with 3 fields or fewer
	p := &Point{330, 10}
	// References have the same syntax for accessing fields 
	println(p.x)
	// The type of p is &Point. It's a reference to Point. References are similar to Go pointers and C++ references.

}



/* STRUCT EXAMPLE 4 */

// Structs can have default values:
struct Foo {
  a int
  b int = 10
}

fn example4() {
	foo := Foo{}
	assert foo.a == 0
	assert foo.b == 10
    println(foo)
}

fn main() {
    example1()
    example2()
    example4()
}