方言を話すおしゃべり猫型ロボット『ミーア』をリリースしました(こちらをクリック)

[Go Memorandum] Static typing, type inference, functions, structures, receivers, Go Modules, Packages, Imports

This article can be read in about 17 minutes.

I’ve started using the Go language, so I’m putting together a memorandum.

The official document is here: https://go.dev/doc/The
Japanese version of “A Tour of Go” is also easy to understand: https://go-tour-jp.appspot.com/list

With static typing and type inference

:= operator

Inside a function,  you can use var short assignment statements instead of declarations  := to make implicit type declarations.

Outside a function, a declaration starting with a keyword (  var,  func, etc.) is required, and  := implicit declaration with is not available.

type inference

When you declare a variable without specifying an explicit type (  := or  var = ), the type of the variable is inferred from the variable on the right.

Go

Go
i := 42           // int
f := 3.142        // float64
g := 0.867 + 0.5i // complex128

Zero value

If a variable is declared without an initial value,   it will be given a zero value.

Go

Go
package main

import "fmt"

func main() {
	var i int     // 0
	var f float64 // 0
	var b bool   // false
	var s string  // 空文字列
	fmt.Printf("%v %v %v %qn", i, f, b, s) // 0 0 false ""
}

type conversion

Unlike C, type conversion in Go requires explicit conversion.

If There’s a variable v and type T, convert the variable to the typeT by T(v).

Go

Go
i := 42
f := float64(i)
u := uint(f)

constant

Constants  are declared in the same way as variables  ,  const using keywords.

Constants can only be characters, strings, booleans, and numeric values.

Constants  := cannot be declared using.

%v: Format specifier

Go uses format specifiers in fmt.Sprintffunctions (and functions in related packages). Go language package stands for “formatted I/O” or “formatted input/output”.fmt%vfmt

%vFormat specifiers are very general and can be applied to a wide variety of data types, from primitive data types (integers, floats, booleans, strings, etc.) to complex data structures (arrays, slices, maps, structs, etc.) used to output the value in the default format.

  • fmt.Sprintfreturns a formatted string, which you can store in a variable or use as input to other functions.
  • fmt.Printfwrites a formatted string directly to standard output (usually the console).

Go

Go
package main

import "fmt"

type Person struct {
    Name string
    Age  int
}

func main() {
    person := Person{Name: "Alice", Age: 30}
    fmt.Printf("Person details: %vn", person)  // Output:Person details: {Alice 30}

    scores := []int{92, 85, 88} // declare an int type array
    fmt.Printf("Scores: %vn", scores)  // Output:Scores: [92 85 88]

    greeting := fmt.Sprintf("Hi, %v. Welcome!", person.Name)
    fmt.Println(greeting)  // Output:"Hi, Alice. Welcome!"
}

function

Functions start with the func keyword and require arguments and return types (static typing)

Write the type name after the variable name

Listed in the order of function name, arguments, and return value

If two or more arguments of a function are of the same type, you can omit all but the last type.

Go

Go
func add(x, y int) int {
	return x + y
}

Functions can return multiple return values

Go

Go
package main

import "fmt"

func swap(x, y string) (string, string) {
	return y, x
}

func main() {
	a, b := swap("hello", "world")
	fmt.Println(a, b)
}

Upper case (Public function)/lower case (Private function)

In Go, if a function or variable name starts with an uppercase letter, that function or variable is considered “exported” and accessible from other packages (Public function). This means that the name is “published” outside the package.

Conversely, names starting with a lowercase letter are accessible only within the package in which they are defined (Private functions). This means that functions and variables that you want to access from other packages must start with an uppercase letter.

Structure

A struct in the Go language structis a collection of fields (also known as properties or attributes) that plays a role similar to classes in many other programming languages. However, structures in Go differ from classes in that methods are defined outside the structure definition, and structures and methods are related through a “receiver.”

Fields in a struct  . are accessed using dots ( ).

Association with method via receiver

Although methods in Go are not directly tied to structs, you can achieve class-like behavior by using a struct instance (or pointer) as a “receiver” for a method.

In the example below, the Greet method is defined using a receiver p of type Person. This allows the Greet method to be called for each instance of the Person type.

Go

Go
package main

import "fmt"

//Declare a Person struct
type Person struct {
    Name string
    Age  int
}

// Defining methods on the Person structure
func (p Person) Greet() {
    fmt.Println("Hello, my name is", p.Name)
}

func main() {
		// Create an instance of the Person structure
    p := Person{Name: "Alice", Age: 30}
    
    // Accessing methods using dot(.)
    p.Greet()  // Output: Hello, my name is Alice

    // Accessing fields using dot(.)
    fmt.Println(p.Name) // Output: Alice
    fmt.Println(p.Age)  // Output: 30
}

pointer receiver

Using a pointer receiver means that the method is called through a pointer to an instance of that type.

With a pointer receiver, a method receives a pointer to an object, that is, the memory address of that object. This allows changes made within the method to be reflected directly in the original object, resulting in passing by address rather than by value.

Resize*Rectangleuses a pointer receiver ( ), so Rectanglechanges to fields within the method are reflected directly in variables mainwithin the function. rect

Go

Go
package main

import "fmt"

type Rectangle struct {
    Width, Height int
}

// Define a method using a pointer receiver
// This method can modify the Rectangle instance
func (r *Rectangle) Resize(newWidth, newHeight int) {
    r.Width = newWidth
    r.Height = newHeight
}

func (r *Rectangle) Area() int {
    return r.Width * r.Height
}

func main() {
    rect := Rectangle{Width: 10, Height: 5}
    fmt.Println("Original dimensions:", rect) //Output: Original dimensions: {10 5}
    fmt.Println("Area:", rect.Area())         //Output: Area: 50

    // method is called to resize the rect
    rect.Resize(20, 10)
    fmt.Println("Resized dimensions:", rect)  // Output: Resized dimensions: {20 10}
    fmt.Println("Area:", rect.Area())         // Output: Area: 200
}

Advantages of pointer receiver:

  • Modifiability: If you change the fields of a structure through a pointer, the changes will be reflected in the original instance. With a value receiver, the changes passed to the method are a copy of the structure, so the changes remain in the local scope.
  • Performance: When working with large structures, making copies is expensive. Pointers improve performance by allowing direct manipulation of data without copying it.

When using pointer receivers:

  • When defining a method that changes the state of an object.
  • When the object is large or changes frequently, performance is a consideration.

Go Modules and the go.mod file

Go modules are a system for managing project dependencies.

go.mod:The file is its central file, containing the name of the module and a list of other modules it depends on.

Module initialization :

Go

Go
$ go mod init example.com/greetings

This command go.modcreates a file and example.com/greetingssets the module name.

Managing dependencies :

Get packages: Get a specific version of a package and add it to your project

Go

Go
$ go get cloud.google.com/go/texttospeech/apiv1

Cleaning up dependencies: go mod tidy Remove unused dependencies and add required ones

Go

Go
$ go mod tidy

Packages

Go programs are made up of packages, and mainexecution starts from the package.

Package declaration :

go mod initIf the module name created with is example.com/greetings, declare it at the beginning of the file containing it package greetings. . This causes the functions and types in that file greetingsto be treated as part of the package.

Go

Go
package greetings

Imports: Factoring alias

You can use single or factored import statements to import packages.

Factored import statement: import multiple packages at once

Go

Go
import (
    "fmt"
    "math"
)

Using aliases: Import packages using aliases to avoid naming conflicts or refer to them by shorter names. You can use this alias to access the package’s functions and types.

In the example below (Google Cloud’s Text-to-Speech API),

  • texttospeechThe alias cloud.google.com/go/texttospeech/apiv1is set for the package. This allows all exposed functions and types within the package texttospeech.to be accessed using the prefix.
  • client, err := texttospeech.NewClient(ctx)NewClientThe function texttospeechis defined in a package and called through an alias.

Go

Go
package main

import (
    "context"
    "fmt"
    "log"

    texttospeech "cloud.google.com/go/texttospeech/apiv1" // import using an alias
)

func main() {
    ctx := context.Background()

    // create a client
    client, err := texttospeech.NewClient(ctx)
    if err != nil {
        log.Fatalf("Failed to create client: %v", err)
    }
    defer client.Close()
}

コメント

Copied title and URL