package main

import (
	"errors"
	"fmt"
	"sync"
	"time"
)

// 常量
const Pi = 3.14159

// 结构体
type Circle struct {
	Radius float64
}

// 方法（值接收者）
func (c Circle) Area() float64 {
	return Pi * c.Radius * c.Radius
}

// 方法（指针接收者）
func (c *Circle) Scale(factor float64) {
	c.Radius *= factor
}

// 接口
type Shape interface {
	Area() float64
}

// 函数（多返回值）
func divide(a, b float64) (float64, error) {
	if b == 0 {
		return 0, errors.New("division by zero")
	}
	return a / b, nil
}

// 主函数
func main() {
	// 变量声明
	var a int = 10
	b := 20
	c, d := 30, 40
	fmt.Println("Variables:", a, b, c, d)

	// 数组与切片
	arr := [3]int{1, 2, 3}
	slice := []int{4, 5, 6}
	slice = append(slice, 7)
	fmt.Println("Array:", arr, "Slice:", slice)

	// 映射
	m := map[string]int{"one": 1, "two": 2}
	fmt.Println("Map:", m)

	// 控制结构
	if a > 5 {
		fmt.Println("a is greater than 5")
	} else {
		fmt.Println("a is not greater than 5")
	}

	for i := 0; i < 3; i++ {
		fmt.Println("Loop:", i)
	}

	switch a {
	case 10:
		fmt.Println("a is 10")
	default:
		fmt.Println("a is not 10")
	}

	// 函数调用
	result, err := divide(10, 2)
	if err != nil {
		fmt.Println("Error:", err)
	} else {
		fmt.Println("Division result:", result)
	}

	// 指针
	x := 10
	p := &x
	*p = 20
	fmt.Println("Pointer:", x)

	// 结构体与方法
	circle := Circle{Radius: 5}
	fmt.Println("Circle area:", circle.Area())
	circle.Scale(2)
	fmt.Println("Scaled circle area:", circle.Area())

	// 接口
	var shape Shape = Circle{Radius: 3}
	fmt.Println("Shape area:", shape.Area())

	// 错误处理
	_, err = divide(10, 0)
	if err != nil {
		fmt.Println("Error:", err)
	}

	// 并发
	var wg sync.WaitGroup
	wg.Add(1)
	go func() {
		defer wg.Done()
		fmt.Println("Running in goroutine")
	}()
	wg.Wait()

	// Channel
	ch := make(chan int)
	go func() {
		ch <- 42
	}()
	value := <-ch
	fmt.Println("Channel value:", value)

	// Select
	ch1 := make(chan string)
	ch2 := make(chan string)
	go func() {
		time.Sleep(1 * time.Second)
		ch1 <- "from ch1"
	}()
	go func() {
		time.Sleep(2 * time.Second)
		ch2 <- "from ch2"
	}()
	select {
	case msg := <-ch1:
		fmt.Println("Select:", msg)
	case msg := <-ch2:
		fmt.Println("Select:", msg)
	case <-time.After(3 * time.Second):
		fmt.Println("Timeout")
	}

	// Defer
	defer fmt.Println("Defer: This runs last")
	fmt.Println("Main function end")
}
