dushaoshuai / dushaoshuai.github.io

https://www.shuai.host
0 stars 0 forks source link

Go: blank identifier #81

Open dushaoshuai opened 1 year ago

dushaoshuai commented 1 year ago

(keep in sync with https://github.com/dushaoshuai/go-usage-examples/blob/master/golang/blank_identifier_test/blank_identifier_test.go)

_(blank identifier)是一个匿名的标识符。在很多地方它可以像 non-blank identifier 一样使用。

Syntax

_ 可以被赋值为任何类型的任何值(同时将该值丢弃);可以被声明为任何类型。

In declarations

package blank_identifier_test // The PackageName must not be the blank identifier.

// an import declaration
// import a package solely for its side-effects (initialization)
import _ "image/png"

// a constant declaration
const _ = 10

// type declaration and type parameter declaration
type _[T comparable, _ any] struct {
    a T
}

// a variable declaration
var _ = 10

// a function declaration
func _() string {
    a := "Go"

_: // a labeled statement
    a += "o"

    return a
}

// struct field
type struc struct {
    _ int
    _ string
    A bool
}

In assignments

func Example_ignore_right_hand_side_values_in_an_assignment() {
    f := func() (int, int) { return 6, 7 }

    _, x, _ := 3, 4, 7
    _, x = f() // evaluate f() but ignore first result value
    x, _ = f() // evaluate f() but ignore second result value

    _ = x   // evaluate x but ignore it
    _ := 10 // error: No new variables on the left side of ':='
}

In for statements with range clause

func Example_in_for_statements_with_range_clause() {
    s := []int{0, 1, 2, 3}

    for range s {
        fmt.Println("One iteration.")
    }
    for _ = range s { // redundant '_' expression
        fmt.Println("One iteration.")
    }

    for i := range s {
        fmt.Println(i, "iteration.")
    }
    for i, _ := range s { // redundant '_' expression
        fmt.Println(i, "iteration.")
    }
    for i, intV := range s {
        fmt.Println(i, intV)
    }
    for _, intV := range s {
        fmt.Println(intV)
    }
}

Usage

Interface checks

如果要确保某个类型实现了某个接口,可以用这种写法,这种写法会在编译时进行检查:

type Iface interface {
    a()
    b()
}

type ImpleIface struct{}

func (i *ImpleIface) a() {}
func (i *ImpleIface) b() {}

// interface checks
// guarantee *ImpleIface satisfies Iface
var _ Iface = (*ImpleIface)(nil)

bounds check hint to compiler

在编译时进行边界检查,而不是运行时,边界检查好像挺费时间的。

// bounds check hint to compiler
func Example_bounds_check_hint_to_compiler() {
    var p [4]int

    // bounds check at compile time
    _ = p[2] // eliminate runtime bounds checks
    p[0] = 0
    p[1] = 1
    p[2] = 2
}

See also