package main
import "fmt"
type MyErr struct{}
func (*MyErr) Error() string { return "my error" }
func returnsTypedNil() error {
var e *MyErr = nil
return e
}
func main() {
var p *int = nil
var s []int = nil
var m map[string]int = nil
var err error = returnsTypedNil()
fmt.Println(p == nil)
fmt.Println(len(s), cap(s), s == nil)
fmt.Println(m["missing"])
fmt.Println(err == nil)
}
package main
import "fmt"
type Point struct{ X, Y int } // comparable
type Bag struct{ Items []string } // not comparable because of slice field
func Contains[T comparable](xs []T, target T) bool {
for _, x := range xs {
if x == target {
return true
}
}
return false
}
func main() {
p1, p2 := Point{1, 2}, Point{1, 2}
fmt.Println(p1 == p2)
m := map[Point]string{p1: "value"}
fmt.Println(m[p2])
fmt.Println(Contains([]string{"a", "b"}, "b"))
var a any = []int{1}
var b any = []int{1}
_, _ = a, b
// fmt.Println(a == b) // panic: comparing uncomparable type []int
}
package main
import "fmt"
func main() {
s := "é🙂"
fmt.Println(len(s)) // bytes: é is 2 bytes, 🙂 is 4 bytes
fmt.Println(len([]rune(s))) // Unicode code points
fmt.Printf("first byte: %x\n", s[0])
for i, r := range s {
fmt.Printf("byte index %d: %q U+%04X\n", i, r, r)
}
}
type UserID int64 // defined type
type AccountID = int64 // alias
func takeInt64(x int64) {}
var u UserID = 10
var a AccountID = 20
takeInt64(int64(u)) // explicit conversion required
takeInt64(a) // ok: AccountID is exactly int64
func (u UserID) String() string {
return fmt.Sprintf("user:%d", u)
}
nan := math.NaN()
fmt.Println(nan == nan)
fmt.Println(math.IsNaN(nan))
m := map[float64]string{nan: "bad key"}
fmt.Println(m[nan]) // lookup fails because nan != nan
Goにおける構造体の埋め込みとは、明示的なフィールド名を付けずに型のみでフィールドを宣言することを指します(例: `type User struct { Person }`)。埋め込まれた値は通常のフィールドとして保持され、`u.Person`のようにアクセスできますが、その公開またはアクセス可能なフィールドやメソッドは昇格(promotion)されるため、呼び出し側は埋め込みフィールドを経由する短縮記法として`u.Name`や`u.Greet()`のようなセレクタを記述できます。埋め込みはコンポジション(合成)であり、古典的な継承ではありません。外側の型が自動的に埋め込まれた型のサブタイプになるわけではありません。昇格したセレクタ名が衝突した場合、Goは推測を行わないため、曖昧な名前は明示的に修飾して指定する必要があり、外側の値から直接セレクタとして参照することはできなくなります。
package main
import "fmt"
type Person struct {
Name string
}
func (p Person) Greet() string {
return "hi " + p.Name
}
type User struct {
Person // embedded field; field name is Person
ID int
}
func main() {
u := User{Person: Person{Name: "Ana"}, ID: 10}
fmt.Println(u.Name) // promoted field: u.Person.Name
fmt.Println(u.Greet()) // promoted method: u.Person.Greet()
fmt.Println(u.Person.Name) // explicit qualification still works
}
package main
import "fmt"
func main() {
base := []int{1, 2, 3, 4}
a := base[:2] // len 2, cap 4
b := base[2:] // len 2, cap 2
a[0] = 99
fmt.Println(base, a, b)
a = append(a, 77) // reuses base's backing array, overwrites base[2]
fmt.Println(base, a, b)
c := append([]int(nil), base[:2]...) // defensive copy
c[0] = 42
fmt.Println(base, c)
}
package main
func collectNoPrealloc(input []int) []int {
var out []int
for _, v := range input {
out = append(out, v*2)
}
return out
}
func collectPrealloc(input []int) []int {
out := make([]int, 0, len(input))
for _, v := range input {
out = append(out, v*2)
}
return out
}