本文深入探讨Go语言中的流程控制语法,包括基本的if-else条件分支、for循环、switch-case多条件分支,以及与特定数据类型相关的流程控制,如for-range循环和type-switch。文章还详细描述了gotofallthrough等跳转语句的使用方法,通过清晰的代码示例为读者提供了直观的指导。

关注微信公众号【TechLeadCloud】,分享互联网架构、云服务技术的全维度知识。作者拥有10+年互联网服务架构、AI产品研发经验、团队管理经验,同济本复旦硕,复旦机器人智能实验室成员,阿里云认证的资深架构师,项目管理专业人士,上亿营收AI产品研发负责人。

引言

在计算机编程中,流程控制是核心的组成部分,它决定了程序应该如何根据给定的情况执行或决策。以下是Go语言所支持的流程控制结构的简要概览:

流程控制类型 代码
if-else条件分支 if condition { } else { }
for循环 for initialization; condition; post { }
switch-case多条件分支 switch value { case v1: ... default: ... }
容器类型的for-range循环 for key, value := range container { }
接口类型的type-switch多条件分支 switch v := value.(type) { case T: ... }
通道类型的select-case多分支 select { case <-ch: ... default: ... }
break跳转语句 break
continue跳转语句 continue
goto跳转语句 goto label
fallthrough跳转语句 fallthrough

在后续部分,我们将深入探讨每种流程控制结构的细节和应用案例,帮助你更好地理解和掌握Go语言的流程控制工具。


if-else条件分支

在Go中,if-else结构提供了条件判断的基本方式。与许多其他编程语言类似,它的基本语法包括测试一个条件,并根据该条件的真假来执行相应的代码块。

基础用法

流程控制类型 代码
if if condition { }
if-else if condition { } else { }
if-else if-else if condition1 { } else if condition2 { } else { }

示例与说明

  1. if

    1. x := 10
    2. if x > 5 {
    3. fmt.Println("x is greater than 5")
    4. }

    当条件 x > 5 成立时,代码会输出 "x is greater than 5"。

  2. if-else

    1. x := 3
    2. if x > 5 {
    3. fmt.Println("x is greater than 5")
    4. } else {
    5. fmt.Println("x is not greater than 5")
    6. }

    因为 x > 5 的条件不成立,所以代码会输出 "x is not greater than 5"。

  3. if-else if-else

    1. x := 5
    2. if x > 10 {
    3. fmt.Println("x is greater than 10")
    4. } else if x < 5 {
    5. fmt.Println("x is less than 5")
    6. } else {
    7. fmt.Println("x is 5")
    8. }

    在这个示例中,由于 x 等于 5,代码会输出 "x is 5"。

带初始化语句的if条件分支

在Go中,if语句可以包含一个初始化语句,通常用于定义在条件测试中使用的临时变量。

流程控制类型 代码
if with initialization if stmt; condition { }

示例与说明

  1. if y := computeValue(); y > 10 {
  2. fmt.Println("y is greater than 10")
  3. } else {
  4. fmt.Println("y is not greater than 10")
  5. }

在这个示例中,我们首先调用 computeValue() 函数(假设它返回一个整数)并将结果赋值给变量 y。然后我们根据 y > 10 的条件来决定输出什么。这种结构允许我们在一个简洁的语句中完成初始化和条件测试。

for循环

for循环是Go语言中的唯一循环结构,但其灵活性足以覆盖其他编程语言中的多种循环结构。通过不同的组合,Go的for循环可以模拟传统的whiledo-while循环。

基础用法

流程控制类型 代码
Basic loop for initialization; condition; post { }
While-like loop for condition { }
Infinite loop for { }

示例与说明

  1. Basic loop

    1. for i := 0; i < 5; i++ {
    2. fmt.Println(i)
    3. }

    这是最常见的for循环形式,上述代码会输出0到4。

  2. While-like loop

    1. x := 5
    2. for x > 0 {
    3. fmt.Println(x)
    4. x--
    5. }

    这种结构模拟了传统的while循环。上述代码会输出从5到1的数字。

  3. Infinite loop

    1. for {
    2. fmt.Println("This will run indefinitely!")
    3. }

    除非有break或其他控制语句,否则这种循环会无限运行。在某些情况下,这可以用于持续等待外部输入或其他中断。

range的for循环

Go语言提供了for-range结构,用于迭代数组、切片、字符串或映射的元素。

流程控制类型 代码
Range loop for key, value := range container { }

示例与说明

  1. nums := []int{1, 2, 3, 4, 5}
  2. for idx, num := range nums {
  3. fmt.Printf("Index: %d, Value: %d\n", idx, num)
  4. }

这个示例中,for-range循环迭代了一个整数切片,并输出每个元素及其索引。同样地,for-range可以用于迭代其他容器类型。


switch-case多条件分支

在Go语言中,switch-case结构提供了一个清晰的方式来进行多条件判断。与其他语言的switch结构略有不同,Go的switch更加灵活,不仅可以用于常量和整数值,还可以用于更复杂的条件判断。

基础用法

流程控制类型 代码
Basic switch switch expression { case value1: ... default: ... }
Multiple values switch expression { case val1, val2: ... }
No expression switch { case condition1: ... }

示例与说明

  1. Basic switch

    1. fruit := "apple"
    2. switch fruit {
    3. case "banana":
    4. fmt.Println("This is a banana.")
    5. case "apple":
    6. fmt.Println("This is an apple.")
    7. default:
    8. fmt.Println("Unknown fruit.")
    9. }

    上述代码会输出 "This is an apple.",因为 fruit 的值是 "apple"。

  2. Multiple values

    1. day := 2
    2. switch day {
    3. case 1, 7:
    4. fmt.Println("Weekend")
    5. case 2, 3, 4, 5, 6:
    6. fmt.Println("Weekday")
    7. default:
    8. fmt.Println("Invalid day")
    9. }

    这个示例中,我们检查 day 是否是工作日还是周末。上述代码会输出 "Weekday"。

  3. No expression

    1. x := 10
    2. switch {
    3. case x > 5:
    4. fmt.Println("x is greater than 5")
    5. case x < 5:
    6. fmt.Println("x is less than 5")
    7. default:
    8. fmt.Println("x is 5")
    9. }

    在这种形式中,switch没有伴随的表达式,它仅仅评估case后的条件。上述代码会输出 "x is greater than 5"。

fallthrough关键字

在Go中,switchcase默认不会"贯穿"(即一旦匹配到一个case,它就会退出switch,不会执行后续的case)。如果你想继续执行下一个case,你需要使用fallthrough关键字。

流程控制类型 代码
Using fallthrough case value: ... fallthrough ...

示例与说明

  1. value := 5
  2. switch value {
  3. case 5:
  4. fmt.Println("Value is 5")
  5. fallthrough
  6. case 6:
  7. fmt.Println("Value is 6 or it fallthrough from 5")
  8. default:
  9. fmt.Println("Another value")
  10. }

上述代码会连续输出 "Value is 5" 和 "Value is 6 or it fallthrough from 5",因为fallthrough使得程序继续执行下一个case。


容器类型的for-range循环

在Go中,for-range结构是处理容器类型(如数组、切片、字符串和映射)的强大工具。它可以非常方便地遍历容器中的所有元素,无需手动处理索引或键。

数组和切片

流程控制类型 代码
遍历数组或切片 for idx, value := range arrayOrSlice { }

示例与说明

  1. nums := []int{1, 2, 3, 4, 5}
  2. for idx, num := range nums {
  3. fmt.Printf("Index: %d, Value: %d\n", idx, num)
  4. }

此代码遍历nums切片的每一个元素,输出其索引和值。

示例与说明

  1. str := "hello"
  2. for idx, char := range str {
  3. fmt.Printf("Index: %d, Char: %c\n", idx, char)
  4. }

此代码遍历str字符串中的每个字符,并输出其索引和字符值。

  1. m := map[string]int{"a": 1, "b": 2, "c": 3}
  2. for key, value := range m {
  3. fmt.Printf("Key: %s, Value: %d\n", key, value)
  4. }

此代码遍历映射m中的每个键值对,输出其键和值。

总的来说,for-range结构为Go程序员提供了一个简单而强大的方式来遍历和操作容器类型的数据。通过简洁的语法,我们可以有效地处理各种容器,而无需担心复杂的索引和边界条件。

接口类型的type-switch多条件分支

在Go语言中,接口类型允许我们处理多种不同的数据类型,但有时我们需要知道接口变量的具体类型。这时,type-switch结构提供了一种优雅的方式来进行类型判断和分支处理。

基础用法

流程控制类型 代码
type-switch switch v := i.(type) { case T: ... default: ... }

示例与说明

  1. 基础type-switch

    1. var i interface{} = "hello"
    2. switch v := i.(type) {
    3. case int:
    4. fmt.Printf("It's an int with value %d\n", v)
    5. case string:
    6. fmt.Printf("It's a string with value %s\n", v)
    7. default:
    8. fmt.Printf("Unknown type: %T\n", v)
    9. }

    此代码首先声明了一个接口类型的变量i并赋值为字符串"hello"。然后,使用type-switch来检查i的动态类型。上述代码将输出:"It's a string with value hello"。

type-switch中的其他用法

type-switch不仅限于基本类型,还可以用于自定义类型、结构体等。

流程控制类型 代码
自定义类型 case CustomType: ...
结构体 case structType: ...

示例与说明

  1. 自定义类型和结构体

    1. type MyString string
    2. type MyStruct struct {
    3. Field int
    4. }
    5. var i interface{} = MyString("hello")
    6. switch v := i.(type) {
    7. case MyString:
    8. fmt.Printf("It's a MyString with value %s\n", string(v))
    9. case MyStruct:
    10. fmt.Printf("It's a MyStruct with field value %d\n", v.Field)
    11. default:
    12. fmt.Printf("Unknown type: %T\n", v)
    13. }

    在这个示例中,我们定义了一个自定义类型MyString和一个结构体MyStruct。然后,我们再次使用type-switch来检查接口变量i的类型。给定的代码将输出:"It's a MyString with value hello"。

总的来说,type-switch结构为Go开发人员提供了一种清晰、简洁的方式来判断接口变量的动态类型,并进行分支处理。掌握这一结构对于在Go中正确处理接口和多态性至关重要。


通道类型的select-case多分支

Go语言中的select关键字是用于处理多个通道的读/写操作。当我们需要同时从多个通道接收或向多个通道发送数据时,select结构提供了一种方式来处理这些操作,使我们可以在一个通道准备好时执行相应的操作。

基础用法

流程控制类型 代码
select-case select { case operation1: ... case operation2: ... }

示例与说明

  1. 基础select-case

    1. ch1 := make(chan int, 1)
    2. ch2 := make(chan string, 1)
    3. ch1 <- 1
    4. ch2 <- "hello"
    5. select {
    6. case i := <-ch1:
    7. fmt.Printf("Received from ch1: %d\n", i)
    8. case s := <-ch2:
    9. fmt.Printf("Received from ch2: %s\n", s)
    10. default:
    11. fmt.Println("No data received")
    12. }

    这段代码定义了两个通道,分别发送一个整数和一个字符串。使用select结构,程序尝试从ch1ch2中接收数据。此代码可能会输出ch1ch2的数据,因为select会随机选择一个可用的case执行。

使用default

select结构中,可以使用default语句来处理当所有通道都不可用时的情况。

示例与说明

  1. 使用default

    1. ch := make(chan int, 1)
    2. select {
    3. case i := <-ch:
    4. fmt.Printf("Received from ch: %d\n", i)
    5. default:
    6. fmt.Println("No data available")
    7. }

    在这个例子中,我们尝试从通道ch中接收数据。但由于没有数据发送到该通道,程序将输出"No data available"。

使用select进行超时处理

利用select结构,我们还可以轻松实现超时机制。

示例与说明

  1. 超时处理

    1. ch := make(chan int, 1)
    2. go func() {
    3. time.Sleep(2 * time.Second)
    4. ch <- 1
    5. }()
    6. select {
    7. case i := <-ch:
    8. fmt.Printf("Received from ch: %d\n", i)
    9. case <-time.After(1 * time.Second):
    10. fmt.Println("Timeout!")
    11. }

    这段代码中,我们试图从通道ch中接收数据,但我们只等待1秒。使用time.After函数,我们可以轻松实现超时逻辑。如果1秒内没有从ch中接收到数据,程序将输出"Timeout!"。

总之,select-case结构为Go开发人员处理多个通道提供了一种非常方便的方式。它不仅允许我们并发地处理多个通道,还可以轻松实现超时和默认操作,使并发编程变得简单而强大。


break跳转语句

在Go语言中,break语句主要用于提前结束一个循环或switchselect等代码块的执行。它使我们可以在满足特定条件时跳出当前执行的代码块。

基础用法

流程控制类型 代码
break break

示例与说明

  1. 在for循环中使用break

    1. for i := 0; i < 10; i++ {
    2. if i == 5 {
    3. break
    4. }
    5. fmt.Println(i)
    6. }

    这段代码将打印从0到4的数字。当i等于5时,break语句会被触发,从而提前结束循环。

  2. 在switch中使用break

    1. switch 2 {
    2. case 1:
    3. fmt.Println("Case 1")
    4. case 2:
    5. fmt.Println("Case 2")
    6. if true {
    7. break
    8. }
    9. fmt.Println("This won't be printed")
    10. case 3:
    11. fmt.Println("Case 3")
    12. }

    在此示例中,当匹配到case 2时,程序会输出"Case 2",然后由于break语句,fmt.Println("This won't be printed")将不会被执行。

带标签的break

在Go中,你还可以使用带标签的break语句来跳出外层循环或其他代码块。

示例与说明

  1. 使用带标签的break

    1. outerLoop:
    2. for i := 0; i < 5; i++ {
    3. for j := 0; j < 5; j++ {
    4. if i*j == 6 {
    5. break outerLoop
    6. }
    7. fmt.Println(i, j)
    8. }
    9. }

    在上述代码中,我们有两个嵌套的for循环。当i*j等于6时,带标签的break语句会被触发,这将导致外层的for循环提前结束。

总体上说,break语句在Go中提供了一种灵活的方式来控制代码块的执行流程。它在循环、switchselect等结构中都有着广泛的应用,使我们可以根据特定的条件提前结束代码块的执行。


continue跳转语句

在Go语言中,continue语句被用于跳过当前循环的剩余语句,并开始下一次循环。不同于break语句,它并不会结束整个循环,而只是跳过当前的迭代。

基础用法

流程控制类型 代码
continue continue

示例与说明

  1. 在for循环中使用continue

    1. for i := 0; i < 10; i++ {
    2. if i%2 == 0 {
    3. continue
    4. }
    5. fmt.Println(i)
    6. }

    上述代码将打印出0到9之间的所有奇数。当i是偶数时,continue语句会被触发,从而跳过当前循环的剩余部分。

  2. 在for-range循环中使用continue

    1. arr := []int{1, 2, 3, 4, 5}
    2. for idx, val := range arr {
    3. if val == 3 {
    4. continue
    5. }
    6. fmt.Printf("arr[%d] = %d\n", idx, val)
    7. }

    这段代码遍历一个整数切片,并打印除3之外的所有元素的索引和值。当元素值为3时,continue语句会被触发,从而跳过当前迭代。

带标签的continue

break语句类似,continue也支持带标签的形式,从而可以在多层嵌套的循环中指定跳转到哪个外层循环的下一次迭代。

示例与说明

  1. 使用带标签的continue

    1. outerLoop:
    2. for i := 0; i < 3; i++ {
    3. for j := 0; j < 3; j++ {
    4. if i == 1 && j == 1 {
    5. continue outerLoop
    6. }
    7. fmt.Println(i, j)
    8. }
    9. }

    在这个例子中,我们有两个嵌套的for循环。当i等于1并且j等于1时,带标签的continue语句会被触发,这会导致直接跳到外层循环的下一次迭代,而内层循环的剩余迭代会被跳过。

总之,continue语句为Go开发人员提供了一种方式,可以在满足特定条件时跳过循环的某次迭代。这使得我们可以更灵活地控制循环的执行流程。


goto跳转语句

在Go语言中,goto 语句允许程序在执行时跳转到指定的标签。尽管goto 语句在现代编程中不那么常用,并且在某些情况下可能引发困惑或使代码难以阅读,但在某些特定场景中,它可能是有用的。

基础用法

流程控制类型 代码
goto goto

示例与说明

  1. 简单的goto使用

    1. func main() {
    2. fmt.Println("Start")
    3. goto end
    4. fmt.Println("This won't be printed")
    5. end:
    6. fmt.Println("End")
    7. }

    在此示例中,程序首先打印"Start",然后跳转到end标签,继续执行下面的代码。因此,fmt.Println("This won't be printed") 不会被执行。

  2. 使用goto进行错误处理

    1. func divide(x, y int) (int, error) {
    2. if y == 0 {
    3. return 0, errors.New("Cannot divide by zero")
    4. }
    5. return x / y, nil
    6. }
    7. func main() {
    8. result, err := divide(10, 0)
    9. if err != nil {
    10. goto handleErr
    11. }
    12. fmt.Println("Result:", result)
    13. return
    14. handleErr:
    15. fmt.Println("Error:", err)
    16. }

    在这个例子中,我们使用goto语句来跳转到错误处理部分。这种做法在某些情况下可以使错误处理更为集中。

尽管goto语句在Go中是可用的,但开发者通常建议在只有真正需要的情况下使用它,因为不当的使用可能导致代码难以理解和维护。当您可以使用其他结构(如ifforswitch)来实现相同的结果时,最好避免使用goto


fallthrough跳转语句

在Go的switch语句中,一旦某个case匹配成功,后续的case将不会再被检查或执行。然而,Go提供了一个特有的关键字:fallthrough,它可以强制执行紧跟它后面的case,无论该case是否匹配。

基础用法

流程控制类型 代码
fallthrough fallthrough

示例与说明

  1. 基础的fallthrough使用

    1. x := 10
    2. switch x {
    3. case 10:
    4. fmt.Println("x is 10")
    5. fallthrough
    6. case 20:
    7. fmt.Println("x is 20")
    8. default:
    9. fmt.Println("x is neither 10 nor 20")
    10. }

    在此示例中,x的值是10,所以程序会首先打印"x is 10"。由于第一个case后面有fallthrough语句,程序继续执行下一个case,即使x的值并不是20,所以还会打印"x is 20"。

  2. fallthrough在非连续case中的使用

    1. y := "apple"
    2. switch y {
    3. case "banana":
    4. fmt.Println("y is banana")
    5. case "apple":
    6. fmt.Println("y is apple")
    7. fallthrough
    8. case "orange":
    9. fmt.Println("y is orange")
    10. default:
    11. fmt.Println("y is neither banana, apple, nor orange")
    12. }

    在这个例子中,当y的值为"apple"时,会打印"y is apple"。然后,由于存在fallthrough语句,"y is orange"也会被打印,即使y的值并不是"orange"。

需要注意的是,虽然fallthrough提供了一种特殊的控制流,但在大多数场景中,过度或不恰当的使用可能导致代码难以阅读和理解。因此,推荐在真正需要时才使用它,并确保代码的意图清晰可见。


关注微信公众号【TechLeadCloud】,分享互联网架构、云服务技术的全维度知识。作者拥有10+年互联网服务架构、AI产品研发经验、团队管理经验,同济本复旦硕,复旦机器人智能实验室成员,阿里云认证的资深架构师,项目管理专业人士,上亿营收AI产品研发负责人。

如有帮助,请多关注

个人微信公众号:【TechLeadCloud】分享AI与云服务研发的全维度知识,谈谈我作为TechLead对技术的独特洞察。

TeahLead KrisChang,10+年的互联网和人工智能从业经验,10年+技术和业务团队管理经验,同济软件工程本科,复旦工程管理硕士,阿里云认证云服务资深架构师,上亿营收AI产品业务负责人。

Go之流程控制大全: 细节、示例与最佳实践的更多相关文章

  1. JAVA之旅(二)——if,switch,for,while,do while,语句嵌套,流程控制break , continue ,函数,重载的示例总结

    JAVA之旅(二)--if,switch,for,while,do while,语句嵌套,流程控制break , continue ,函数,重载的示例总结 JAVA的思想真的很重要,所以要专心的学-- ...

  2. Java 关键字、标识符、注释、常量与变量、数据类型,算术、赋值、比较、逻辑、位、三元运算符和流程控制、break、continue【3】

    若有不正之处,请多多谅解并欢迎批评指正,不甚感激.请尊重作者劳动成果: 本文原创作者:pipi-changing本文原创出处:http://www.cnblogs.com/pipi-changing/ ...

  3. Go语言入门(二)Go语言中的变量、常量、数据类型、流程控制以及函数

    Go语言中的变量 通常用var关键声明变量,有常规方式和简化方式. 常规方式: var name1 type1 name1 = value1 //赋值 简化方式: var name2 = value1 ...

  4. Python黑帽编程2.4 流程控制

    Python黑帽编程2.4  流程控制 本节要介绍的是Python编程中和流程控制有关的关键字和相关内容. 2.4.1 if …..else 先上一段代码: #!/usr/bin/python # - ...

  5. 高性能JavaScript笔记二(算法和流程控制、快速响应用户界面、Ajax)

    循环 在javaScript中的四种循环中(for.for-in.while.do-while),只有for-in循环比其它几种明显要慢,另外三种速度区别不大 有一点需要注意的是,javascript ...

  6. JavaScript学习笔记——流程控制

    javascript流程控制流程:就是程序代码的执行顺序.流程控制:通过规定的语句让程序代码有条件的按照一定的方式执行. 一.顺序结构 按照书写顺序来执行,是程序中最基本的流程结构. 二.选择结构(分 ...

  7. lishell学习之路:流程控制(case)

    流程控制case语句: 介绍:多分支case条件语句 1.case语句和if..elif..else语句一样都是多分支条件语句,不过和if多分支条件语句不同的是,case语句只能判断一种条件关系,而i ...

  8. iOS开发Swift篇—(六)流程控制

    iOS开发Swift篇—(六)流程控制 一.swift中的流程控制 Swift支持的流程结构如下: 循环结构:for.for-in.while.do-while 选择结构:if.switch 注意:这 ...

  9. [Shell]条件判断与流程控制:if, case, for, while, until

    ---------------------------------------------------------------------------------------------------- ...

  10. (四)、 nodejs中Async详解之一:流程控制

    为了适应异步编程,减少回调的嵌套,我尝试了很多库.最终觉得还是async最靠谱. 地址:https://github.com/caolan/async Async的内容分为三部分: 流程控制:简化十种 ...

随机推荐

  1. JavaWeb编程面试题——Spring Framework

    引言 面试题==知识点,这里所记录的面试题并不针对于面试者,而是将这些面试题作为技能知识点来看待.不以刷题进大厂为目的,而是以学习为目的.这里的知识点会持续更新,目录也会随时进行调整. 关注公众号:编 ...

  2. GO 项目依赖管理:go module总结

    转载请注明出处: 1.go module介绍 go module是go官方自带的go依赖管理库,在1.13版本正式推荐使用 go module可以将某个项目(文件夹)下的所有依赖整理成一个 go.mo ...

  3. 7. 特殊SQL的执行

    1. 模糊查询 ‍ 演示代码: /** * 测试模糊查询 * @param mohu * @return */ List<User> testMohu(@Param("mohu& ...

  4. Ryu控制器教程

    RYU不要使用apt的方法安装,这样的安装是不完整的, 并且相关文件不易查找. 1.下载ryu源码 cd cd Desktop git clone https://gitee.com/lpm-123/ ...

  5. VSCode中打开NodeJS项目自动切换对应版本的配置

    这几年搞了不少静态站点,有的是Hexo的,有的是VuePress的.由于不同的主题对于NodeJS的版本要求不同,所以本机上不少NodeJS的版本. 关于如何管理多个NodeJS版本,很早之前就写过用 ...

  6. vue和servlet 前后端分离 (复习)

    一.vue复习 1.vue的使用步骤: (1)导入vue.js (2)创建除body以外最大的div标签,给定id值 (3)创建vue对象 new Vue({ el:"#app", ...

  7. Thread 和 ThreadPool 简单梳理(C#)【并发编程系列】

    〇.前言 对于 Thread 和 ThreadPool 已经是元老级别的类了.Thread 是 C# 语言对线程对象的封装,它从 .NET 1.0 版本就有了,然后 ThreadPool 是 .Net ...

  8. Spring Data MongoDB 使用

    本文为博主原创,转载请注明出处: Spring Data MongoDB 是 Spring Data 系列的一部分,它提供了与 MongoDB 的集成和操作支持,类似于 JPA 对关系型数据库的支持. ...

  9. 【最新】Delphi XE7 绿色版下载,亲测可用!

    最后更新时间 2017-12-05. 本文整理自2ccc盒子iny的帖子 → 链接到原贴 破解 → 链接 一.绿色版介绍 绿色版除了不包含 FastReport(RAD Studio自带的FastRe ...

  10. 在Java项目中使用redisson实现分布式锁

    Redisson自定义注解实现分布式锁 在Java项目中使用Redission自定义注解实现分布式锁: 添加Redission依赖项:在项目的pom.xml中添加Redission依赖项: <d ...