go语言基础 | 青训营
Go语言优点:
- 高性能、高并发:Go语言以并发为设计核心,通过轻量级线程(goroutines)和通信机制(channels)实现高效的并发编程。
- 语法简单、学习曲线平缓:Go语言的语法设计简洁易懂,使得新手可以很快上手。
- 丰富的标准库:Go语言拥有许多内置的标准库,提供了各种功能,如网络编程、文件操作等,使得开发变得更加便捷。
- 完善的工具链:Go语言提供了完整的工具链,包括编译器、格式化工具、测试工具等,为开发者提供了良好的开发环境。
- 静态链接:Go语言的程序静态链接,依赖少,部署简单。
- 快速编译:Go语言编译速度快,能够快速生成可执行文件。
- 跨平台:Go语言支持跨多种平台编译,使得开发者可以方便地在不同平台上运行其程序。
- 垃圾回收:Go语言具有自动垃圾回收机制,开发者无需手动管理内存。
Go语言基本语法:
变量定义:
var 变量名 (类型) = 值
:显示声明并初始化变量。变量名 := 值
:简短声明方式,Go语言会根据值自动推导变量类型。
if语句:
arduinoCopy code
if 等式 {
// 条件成立时执行的代码
}
for循环:
for {}
:无限循环。for 初始; 等式; i++ { continue; break; }
:带有初始语句、循环条件和后续语句的循环形式,支持和控制。continue``break
switch语句:
switch语句只会执行匹配的一个case,执行后自动退出switch。
arduinoCopy code
switch (值) {
case 1:
// 执行当值等于1时的代码
case 2:
// 执行当值等于2时的代码
}
数组:
cssCopy code
var 变量名 [5] (类型)
切片(可变数组):
切片是对数组的一个连续片段的引用。 通过内置函数创建。make
goCopy code
定义s := make([]string, 3)
添加s = append(s, "d")
map(哈希):
map是一种键值对集合。 通过内置函数创建。make
goCopy code
m := make(map[string]int)
m["键"] = 值
r, ok := m["键"] // 检查是否存在该键,r为键对应的值,ok为布尔值,表示是否存在
delete(m, "键") // 删除键值对
结构体:
结构体是一种用户自定义的数据类型,用于存储不同类型的数据。
goCopy code
type user struct {
name string
password string
}
错误处理:
Go语言中通过返回error类型来处理错误。 一般约定如果函数执行成功,则error为nil,否则返回对应的错误信息。
goCopy code
import {
"errors"
}
func 函数名(v *user, **err error**) *user {
return &u, nil // 返回成功
return nil, errors.New("not found") // 返回错误信息
}
输出:
在输出时可以使用、、等格式化字符串来显示变量的值。%v
%+v
%#v
guessing-game 猜谜游戏
guessing-game 猜谜游戏源代码
goCopy code
package main
import (
"bufio"
"fmt"
"math/rand"
"os"
"strconv"
"strings"
"time"
)
func main() {
maxNum := 100
rand.Seed(time.Now().UnixNano())
secretNumber := rand.Intn(maxNum)
fmt.Println("The secret number is ", secretNumber)
fmt.Println("Please input your guess")
reader := bufio.NewReader(os.Stdin)
for {
input, err := reader.ReadString('\n')
if err != nil {
fmt.Println("An error occurred while reading input. Please try again", err)
continue
}
input = strings.TrimSpace(input) // Remove leading and trailing whitespace characters
guess, err := strconv.Atoi(input)
if err != nil {
fmt.Println("Invalid input. Please enter an integer value")
continue
}
fmt.Println("Your guess is", guess)
if guess > secretNumber {
fmt.Println("Your guess is bigger than the secret number. Please try again")
} else if guess < secretNumber {
fmt.Println("Your guess is smaller than the secret number. Please try again")
} else {
fmt.Println("Correct, you Legend!")
break
}
}
}
guessing-game 猜谜游戏结果
simpledict 命令行词典
simpledict 命令行词典源代码
package main
import (
"bufio"
"fmt"
"io"
"os"
"strings"
)
func find(pattern, filename string) error {
file, err := os.Open(filename)
if err != nil {
return err
}
defer file.Close()
fileReader := bufio.NewReader(file)
lineIdx := 0
fmt.Printf("Results for pattern: %q in file: %s\n", pattern, filename)
fmt.Println(strings.Repeat("=", 50))
for {
line, err := fileReader.ReadString('\n')
if err == io.EOF {
break
}
lineIdx++
if strings.Contains(line, pattern) {
fmt.Printf("Line %d: %s", lineIdx, strings.Trim(line, "\n"))
}
}
fmt.Println(strings.Repeat("=", 50))
return nil
}
func main() {
if len(os.Args) != 3 {
fmt.Println("Usage: ggrep <pattern> <filename>")
os.Exit(1)
}
pattern := os.Args[1]
filename := os.Args[2]
err := find(pattern, filename)
if err != nil {
fmt.Printf("Error: %+v\n", err)
}
}
proxy SOCKS5 代理
proxy SOCKS5 代理源代码
goCopy code
package main
import (
"bufio"
"context"
"encoding/binary"
"errors"
"fmt"
"io"
"log"
"net"
)
const socks5Ver = 0x05
const cmdBind = 0x01
const atypIPV4 = 0x01
const atypeHOST = 0x03
const atypeIPV6 = 0x04
func main() {
server, err := net.Listen("tcp", "127.0.0.1:1080")
if err != nil {
log.Fatalf("Failed to start SOCKS5 proxy server: %v", err)
}
log.Println("SOCKS5 proxy server started on 127.0.0.1:1080")
defer server.Close()
for {
client, err := server.Accept()
if err != nil {
log.Printf("Accept failed: %v", err)
continue
}
go process(client)
}
}
func process(conn net.Conn) {
defer conn.Close()
// Perform SOCKS5 handshake and authentication
err := auth(conn)
if err != nil {
log.Printf("Client %v authentication failed: %v", conn.RemoteAddr(), err)
return
}
// Connect to the destination server through the proxy
err = connect(conn)
if err != nil {
log.Printf("Client %v connection failed: %v", conn.RemoteAddr(), err)
return
}
}
func auth(conn net.Conn) error {
reader := bufio.NewReader(conn)
// Read SOCKS5 version and supported authentication methods
ver, err := reader.ReadByte()
if err != nil {
return fmt.Errorf("read ver failed: %w", err)
}
if ver != socks5Ver {
return fmt.Errorf("not supported ver: %v", ver)
}
methodSize, err := reader.ReadByte()
if err != nil {
return fmt.Errorf("read methodSize failed: %w", err)
}
methods := make([]byte, methodSize)
_, err = io.ReadFull(reader, methods)
if err != nil {
return fmt.Errorf("read methods failed: %w", err)
}
// Respond with the selected method (no authentication required)
_, err = conn.Write([]byte{socks5Ver, 0x00})
if err != nil {
return fmt.Errorf("write failed: %w", err)
}
return nil
}
func connect(conn net.Conn) error {
reader := bufio.NewReader(conn)
// Read SOCKS5 request header
header := make([]byte, 4)
_, err := io.ReadFull(reader, header)
if err != nil {
return fmt.Errorf("read header failed: %w", err)
}
ver, cmd, _, atyp := header[0], header[1], header[2], header[3]
if ver != socks5Ver {
return fmt.Errorf("not supported ver: %v", ver)
}
if cmd != cmdBind {
return fmt.Errorf("not supported cmd: %v", cmd)
}
addr := ""
switch atyp {
case atypIPV4:
ip := make([]byte, 4)
_, err := io.ReadFull(reader, ip)
if err != nil {
return fmt.Errorf("read IPv4 address failed: %w", err)
}
addr = net.IP(ip).String()
case atypeHOST:
hostSize, err := reader.ReadByte()
if err != nil {
return fmt.Errorf("read hostSize failed: %w", err)
}
host := make([]byte, hostSize)
_, err = io.ReadFull(reader, host)
if err != nil {
return fmt.Errorf("read host failed: %w", err)
}
addr = string(host)
case atypeIPV6:
return errors.New("IPv6: not supported yet")
default:
return errors.New("invalid atyp")
}
portBytes := make([]byte, 2)
_, err = io.ReadFull(reader, portBytes)
if err != nil {
return fmt.Errorf("read port failed: %w", err)
}
port := binary.BigEndian.Uint16(portBytes)
// Connect to the destination server
dest, err := net.Dial("tcp", fmt.Sprintf("%v:%v", addr, port))
if err != nil {
return fmt.Errorf("dial destination failed: %w", err)
}
defer dest.Close()
log.Printf("Connected to destination %v:%v through SOCKS5 proxy", addr, port)
// Respond with success to the client
_, err = conn.Write([]byte{socks5Ver, 0x00, 0x00, atypIPV4, 0, 0, 0, 0, 0, 0})
if err != nil {
return fmt.Errorf("write response failed: %w", err)
}
// Copy data between client and destination
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
go func() {
_, _ = io.Copy(dest, reader)
cancel()
}()
go func() {
_, _ = io.Copy(conn, dest)
cancel()
}()
<-ctx.Done()
log.Printf("Connection closed: %v", conn.RemoteAddr())
return nil
}
基本 Web 服务器:创建一个简单的 HTTP 服务器
基本 Web 服务器源代码
goCopy code
package main
import (
"fmt"
"net/http"
)
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, World!")
}
func main() {
http.HandleFunc("/", handler)
fmt.Println("Server started at http://localhost:8080")
http.ListenAndServe(":8080", nil)
}
JSON 编码和解码
JSON 编码和解码源代码
goCopy code
package main
import (
"encoding/json"
"fmt"
)
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
// Encoding a struct to JSON
p1 := Person{Name: "Alice", Age: 30}
jsonData, err := json.Marshal(p1)
if err != nil {
fmt.Println("Error encoding to JSON:", err)
return
}
fmt.Println("Encoded JSON:", string(jsonData))
// Decoding JSON to a struct
var p2 Person
err = json.Unmarshal(jsonData, &p2)
if err != nil {
fmt.Println("Error decoding JSON:", err)
return
}
fmt.Printf("Decoded Person: %+v\n", p2)
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)