为了提高效率,有时需要两个函数一起运行。
f() // 程序会等到 f() 执行完才会执行下一步
go f() // 创建一个 goroutine 来调用 f() ,程序不等待,直接执行下一步
package main
import (
"fmt"
"time"
)
func main() {
go spinner(100 * time.Millisecond)
const n = 45
fibN := fib(n)
fmt.Printf("\rFibonacci(%d) = %d\n", n, fibN)
}
func spinner(delay time.Duration) {
for {
for _, r := range `-\|/` {
fmt.Printf("\r%c", r)
time.Sleep(delay)
}
}
}
func fib(x int) int {
if x < 2 {
return x
}
return fib(x-1) + fib(x-2)
}
输出结果
Fibonacci(45) = 1134903170
package main
import (
"io"
"log"
"net"
"time"
)
func main() {
listener, err := net.Listen("tcp", "localhost:8000")
if err != nil {
log.Fatal(err)
}
for {
conn, err := listener.Accept()
if err != nil {
log.Print(err)
continue
}
go handleConn(conn)
}
}
func handleConn(c net.Conn) {
defer c.Close()
for {
_, err := io.WriteString(c, time.Now().Format("2006-01-02 15:04:05\n"))
if err != nil {
return
}
time.Sleep(1 * time.Second)
}
}
还需要一个配套的客户端来访问上面的 tcp 服务
package main
import (
"io"
"log"
"net"
"os"
)
func main() {
conn, err := net.Dial("tcp", "localhost:8000")
if err != nil {
log.Fatal(err)
}
defer conn.Close()
mustCopy(os.Stdout, conn)
}
func mustCopy(dst io.Writer, src io.Reader) {
if _, err := io.Copy(dst, src); err != nil {
log.Fatal(err)
}
}
输出示例
2024-01-20 00:33:15
2024-01-20 00:33:16
2024-01-20 00:33:17
2024-01-20 00:33:18
2024/01/20 00:33:19
package main
import (
"flag"
"fmt"
"os"
)
func main() {
flag.Parse()
roots := flag.Args()
if len(roots) == 0 {
roots = []string{"."} // 默认当前目录
}
fileSizes := make(chan int64)
go func() {
for _, root := range roots {
walkDir(root, fileSizes)
}
close(fileSizes)
}()
var nFiles, nBytes int64
for size := range fileSizes {
nFiles++
nBytes += size
}
printDiskUsage(nFiles, nBytes)
}
func printDiskUsage(nFiles, nBytes int64) {
fmt.Printf("%d files %.1f GB (%1.f MB)\n", nFiles, float64(nBytes)/1e9, float64(nBytes)/1e6)
}
func walkDir(dir string, fileSizes chan<- int64) {
for _, entry := range dirEntries(dir) {
if entry.IsDir() {
// subdir := filepath.Join(dir, entry.Name())
// walkDir(subdir, fileSizes)
} else {
fileInfo, err := entry.Info()
if err != nil {
fmt.Fprintf(os.Stderr, "du1: %v\n", err)
} else {
fileSizes <- fileInfo.Size()
}
}
}
}
func dirEntries(dir string) []os.DirEntry {
entries, err := os.ReadDir(dir)
if err != nil {
fmt.Fprintf(os.Stderr, "du1: %v\n", err)
return nil
}
return entries
}
输出
53 files 9.8 GB (9795 MB)