当前位置: 首页 > news >正文

Golang快速上手02/Golang基础

4.控制语句

4.1条件控制语句
4.1.1if-elseif-else
  • 与clang不同,if不需要加()

    if <condition1> {
        <block1>
    } else if <condition2> {
        <block2>
    } else {
        <block0>
    }
    
  • 示例

    a := 10
    if a > 5 {
        fmt.Println("a > 5")
    } else if a == 5 {
        fmt.Println("a == 5")
    } else {
        fmt.Println("a < 5")
    }
    
4.1.2switch-case语句
  • switch-case

    switch <variable> {
    case <value1>:
        <block1>
    case <value2>:
        <block2>
    ...
    default:
        <block0>
    }
    
    switch {
    case <condition1>:
    	<block1>
    case <condition2>:
    	<block2>
    ...
    default:
        <block0>
    }
    
  • 示例

    package main
    
    func main() {
    	a := 5
    	switch a {  // value值去判断
    	case 1:
    		println("a = 1")
    	case 2:
    		println("a = 2")
    	case 3:	
    		println("a = 3")
    	case 4:
    		println("a = 4")
    	case 5:
    		println("a = 5")
    	}
    
    	score := 90
    	switch {     // 表达式
    	case score > 90:
    		println("A")
    	case score > 80:
    		println("B")
    	case score > 70:
    		println("C")
    	case score > 60:
    		println("D")
    	default:
    		println("E")
    	}
    }
    
4.1.3select-case
  • 格式

    select {
    case <expression1>:
        <block1>
    case <expression2>:
        <block2>
    default:
        <block0>
    }
    
    1. expression必须是通信操作
    2. select讲随机抽取一个case,如果通信成功则运行block;如果失败才执行default
  • 示例

    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    var c1 = make(chan string)
    var c2 = make(chan string)
    
    func Thread1() {
    	time.Sleep(time.Millisecond * 2100)
    	c1 <- "Thread1 is ready."
    }
    
    func Thread2() {
    	time.Sleep(time.Millisecond * 2100)
    	c1 <- "Thread2 is ready."
    }
    
    func main() {
    	go Thread1()  // 加go,开辟线程,去接受data
    	go Thread2()
    	// time.Sleep(10 * time.Millisecond)
    	for i := 0; i < 10; i++ {
    		select {
    		case msg1 := <-c1:
    			fmt.Println(msg1)
    		case msg2 := <-c2:
    			fmt.Println(msg2)
    		default:
    			fmt.Println("default")
    			time.Sleep(time.Millisecond * 500)
    		}
    	}
    }
    
    default
    default
    default
    default
    default
    Thread2 is ready.
    Thread1 is ready.
    default
    default
    default
    
    default
    default
    default
    default
    default
    Thread1 is ready.
    Thread2 is ready.
    default
    default
    default
    
    • 这两种都有可能,因为case是随机的
4.2循环控制语句
4.2.1for语句
GolangClang
for ; ; { }for (; ; ) { ; }
for { }while () { ; }
for { }while (true) { ; }
  • Golang 中的 for 语句 ; 间的语句也可以是空语句
  1. continue:跳转到下一个循环

    for i := 0; i < 5; i++ {
        if i == 3 {
            continue
    	}
        fmt.Println(i)
    }
    
    // 0
    // 1
    // 2
    // 4
    
  2. break:跳出循环

    for i := 0; i < 5; i++ {
        if i == 3 {
            break
    	}
        fmt.Println(i)
    }
    
    // 0
    // 1
    // 2
    
  3. goto:跳转到指定标签

    for i := 0; i < 5; i++ {
        if i == 3 {
            goto tag
    	}
        fmt.Println(i)
    }
    tag:
    
    // 0
    // 1
    // 2
    
  4. for-range

    slice := []int{1, 2, 3, 4, 5}
    for key, value := range slice {
        fmt.Println(key, value)
    }
    
    channel := make(chan int, 10)
    for value := range channel {
        fmt.Println(value) // 这里会阻塞,因为通道是空的,缓冲区是空的
    }
    
    • 数组、stringslicemapchannel 等都可以使用 for-range 语句遍历。其中 channel 没有 key 且阻塞。

    • 闭包

      package main
      
      import "fmt"
      
      func main() {
          var funcs []func()            // 定义一个函数切片
          for i := 0; i < 3; i++ {
              funcs = append(funcs, func() { // 向切片添加匿名函数
                  fmt.Println(i)
              })
          }
          for _, f := range funcs {
              f() // 输出: 3 3 3
          }
      }
      
4.3特殊控制语句
4.3.1defer
  1. defer语句用于操作延迟到函数结束执行

  2. defer语句将操作压栈,在结束时逆序执行

  3. defer语句必须使用函数

    • 格式

      defer <functionCall>

    • 示例

      package main
      
      func test() {
      	defer println("test")
      	println("hello")
      }
      
      func main() {
      	test() // hello test
      }
      
4.3.2特殊使用
  • 引用

    谈及 defer 原理,defer 语句将延迟操作压栈,压栈数据包括:函数名、函数参数(临时)地址。后面的所有怪用都基于这一原理,defer 语句可以修改和访问本该已卸载的内存。defer 压栈后实际对地址又进行了一次引用,因此 Golang 的垃圾回收机制(GC)实际没有卸载这些内存。

  • 修改函数的返回值

    package main
    
    func Demo() (s string) {
    	s = "hello"
    	defer func() { s = "world" } ()
    	return s
    }
    
    func main() {
    	println(Demo()) // world
    }
    
  • 循环延迟返回相同返回值

    func Demo1() {
        for i := 0; i < 3; i++ {
            defer fmt.Println(i)
        }
    }
    // 3
    // 3
    // 3
    // 闭包
    func Demo2() {
        for i := 0; i < 3; i++ {
            i := i
            defer fmt.Println(i)
        }
    }
    // 0
    // 1
    // 2
    
4.3.3go语句
  • go 语句将创建一个 gorountine,可以简单认为是一个线程或协程。go 语句的对象是一个函数,将函数作为一个新的线程运行。

    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    func thread() {
    	for i := 0; i < 5; i++ {
    		fmt.Println("Thread", i)
    		time.Sleep(time.Microsecond * 50)
    	}
    }
    
    func main() {
    	go thread()
    	for i := 0; i < 5; i++ {
    		fmt.Println("Main", i)
    		time.Sleep(time.Microsecond * 50)
    	}
    }
    
    /*
    Main 0
    Thread 0
    Thread 1
    Main 1
    Main 2
    Thread 2
    Main 3
    Thread 3
    Thread 4
    Main 4
    */
    
    • 多线程会使用,管道的读写需要配合创建线程使用
4.4异常处理
4.4.1panic&&recover
  1. panic:抛出异常

  2. recover:返回异常

    package main
    
    import (
    	"fmt"
    )
    
    func fn1() {
    	panic("error")
    }
    
    func fn2() {
    	fmt.Println("fn2")
    }
    
    func fn3() {
    	defer func() {
    		err := recover()
    		if err != nil {
    			fmt.Println(err)
    		}
    	}()
    	panic("this is a error")
    }
    
    func main() {
    	fn3()
    }
    
    • 没有try catch,所以通过recover()来查看是否有异常抛出,来实现try catch的功能
    • panic可以在任何地方用。而recover必须在defer里
4.4.2error
  • error接口原型

    type error interface {
        Error() string
    }
    
  1. 构造异常,都是error类型

    err := errors.New("异常信息")  // error: "异常信息"
    err := fmt.Errorf("错误信息: %v", "异常信息")  // errors.New(fmt.Sprintf(...))
    
  2. 类似于其它语言的try…catch

    func myFn() {
    	defer func() {
    		err := recover()
    		if err != nil {
    			fmt.Println("给管理员发送邮件,得知错误")
    		}
    	}()
    	err := readFile("xxx.go")
    	if err != nil {
    		panic(err)
    	}
    }
    
  3. 示例

    package main
    
    import (
    	"fmt"
    )
    
    func readFile(filename string) error {
    	if filename == "main.go" {
    		return nil
    	} else {
    		// errors.New("异常信息")
    		return fmt.Errorf("读取文件失败")
    	}
    }
    
    func myFn() {
    	defer func() {
    		err := recover()
    		if err != nil {
    			fmt.Println("给管理员发送邮件,得知错误")
    		}
    	}()
    	err := readFile("xxx.go")
    	if err != nil {
    		panic(err)
    	}
    }
    
    func main() {
    	myFn()
    	fmt.Println("继续执行......")
    }
    

5.包管理

5.1包的分类
  1. 系统内置包:fmt、strings

  2. 自定义包:

    • 小写的名称(包括方法和变量)代表私有,大写代表公有

    • 直接import <路径>就可以使用

  3. 第三方包

    • 下载go get <地址>或者import路径后使用go mod tity下载使用未下载的包、删除未使用的包,后会出现sum.mod的文件
5.2包管理工具go mod在·
  1. go mod init <项目名称>:初始化项目
    • 会生成go.mod文件
    • 包名为 main 的包为应用程序的入口包,这种包编译后会得到一个可执行文件,而编译不包含 main 包的源代码则不会得到可执行文件!
    • 别名,在前面写一个别名即可t “fmt”,在前面加_,命名为此,如果不使用不会报错
  • 参考https://blog.csdn.net/TimeLies_Sea/article/details/131581569

相关文章:

  • Nginx将tomcat项目转发。将非80/443端口口转为80或443及https
  • mysql架构查询执行流程(图解+描述)
  • WPF高级 | WPF 3D 图形编程基础:创建立体的用户界面元素
  • ChatGPT 提示词框架
  • mysql数据迁移到SQLserver: 构建数据迁移脚本
  • 2025年网校系统源码开发趋势:技术革新的教育培训APP搭建实战
  • WPF11-附加属性
  • 推荐律师事务管理系统(SpringCloud+mysql+rocketmq+deepseek)
  • Qt 中,**信号与槽(Signals Slots)机制
  • docker通用技术介绍
  • 基于Python socket库构建的基于 P2P 的文件共享系统示例
  • 深入理解消息队列
  • 【TypeScript】TypeScript的应用实例
  • 重磅 | Cloud Ace 推出 GenAIOps 服务:加速企业生成式 AI 商业落地
  • wayland桌面录屏,屏幕录制,Linux屏幕录制
  • (功能测试)第五章 APP性能测试 常用的APP命令格式 补充与总结
  • React + TypeScript 数据血缘分析实战
  • DeepSeek R1 部署笔记(个人无框架部署,缓慢更新中)
  • Spring AOP 切面打印日志完整版
  • ubuntu离线安装Ollama并部署Llama3.1 70B INT4并对外发布服务
  • 网站降权怎么做/青岛关键词排名系统
  • 简单的网站设计案例/怎么做一个网站页面
  • wordpress主题知言/seo下拉优化
  • 如何建设网站/网站提交收录入口链接
  • 南昌做网站要多少钱/百度搜索使用方法
  • 安徽建工招采平台/英文外链seo兼职