// https://www.dolthub.com/blog/2023-10-20-golang-pitfalls-3/
type slice struct {
array unsafe.Pointer
len int
cap int
}
sliceA := []int{1, 2, 3}
sliceB := append(sliceA, 4)
sliceC := append(sliceA, 5)
sliceC[0] = 0
fmt.Println(*(*slice)(unsafe.Pointer(&sliceA))) // prints {0xc00001a018 3 3}If you assign a value to an interface, even if that value is nil, the interface itself is not nil.
type MyType struct{}
func (m *MyType) Write(p []byte) (n int, err error) {
fmt.Println("called.")
return len(p), nil
}
type MyInterface interface {
MyMethod()
}
func main() {
var myType *MyType // myType = nil
test(myType)
var myInterface MyInterface
if myInterface == nil {
fmt.Println("The interface is nil.")
}
}
func test(out io.Writer) {
if out != nil {
fmt.Println("interface is not nil.")
}
if v, ok := out.(*MyType); ok && v == nil {
fmt.Println("Underlying value of the interface is nil.")
}
}type MyInterface interface {
MyMethod()
}
func main() {
var myInterface MyInterface
if myInterface == nil {
fmt.Println("The interface is nil.")
}
}E.g. passing a slice of a type(A) as the argument to a function. Type A satisifes the function, but []A does not. Convert the type array to an interface array.
type RequirementConstrained interface {
GetRequirements() []Requirement
}
type Requirement int
type A struct {
requirements []Requirement
}
func (a A) GetRequirements() []Requirement {
return a.requirements
}
type B struct {
requirements []Requirement
}
func (b B) GetRequirements() []Requirement {
return b.requirements
}
func FilterByRequirements(entity RequirementConstrained) RequirementConstrained {
return entity
}
func main() {
var aents []A
var filtered []RequirementConstrained
for _, a := range aents {
filtered = append(filtered, FilterByRequirements(a))
}
}func main() {
str := "你好" // Chinese characters for "Hello"
// Accessing individual bytes (byte = uint8) in the string
for i := 0; i < len(str); i++ {
fmt.Printf("%U)", str[i])
}
fmt.Println()
// Accessing individual runes (Unicode code points - UTF8, rune = int32) in the string
for _, r := range str {
fmt.Printf("%c ", r)
}
fmt.Println()
}When comparing two instances of a value type in Go, it checks whether their field values are equal.
type someStr struct{ text string }
a := someString{"test1"}
b := someString{"test1"}
fmt.Println(a == b) // true
a = &someString{"test1"}
b = &someString{"test1"}
fmt.Println(a == b) // falsereflect.TypeOf(v).String()
type MyInt interface{}
var x MyInt = 5
res := x.(int)
fmt.Printf("type: %T value: %[1]v\n", res)// Animal interface
type Animal interface {
Speak() string
}
// Trainer interface with an additional method
type Trainer interface {
Train() string
}
// Dog type implementing both Animal and Trainer interfaces
type Dog struct{}
func (d Dog) Speak() string {
return "Woof! Woof!"
}
func (d Dog) Train() string {
return "Sit! Stay!"
}
type SpeakTrain interface {
Speak() string
Train() string
}
func main() {
var t Trainer
t = PoliceDog{}
// Type assertion to access the larger set of methods in the Trainer interface
if st, ok := x.(SpeakTrain); ok {
fmt.Println("Train:", st.Train())
fmt.Println("Speak:", st.Speak())
} else {
fmt.Println("Type assertion failed")
}
}type I interface {
F()
G()
}
type S struct{}
func (S) F() {}
func (*S) G() {}
var _ I = (*S)(nil) // *S Satisifes the interface I.
var _ I = S{} // S does not satisfy the interface I.import "github.com/cespare/xxhash/v2"
type Hasher struct{}
// Hash implements the Hasher interface.
// Because this is a direct call on a concrete type,
// the compiler can inline it.
func (h XxHasher) Hash(key []byte) uint64 {
return xxhash.Sum64(key)
}
func (b *Buffer) Compact[H Hasher]() (done bool, newOffsets [][2]uint64, err error) {
// Get a zero-value instance of the Hasher type.
// Since our XxHasher is an empty struct,
// this variable is zero-cost and compiles away.
var hasher H
// This is now a direct call on a concrete type,
// not an indirect function-pointer call.
hash := hasher.Hash(b.keyBuf)
// ...
}
b := Buffer{}
b.Compact[Hasher]() // Example usage.