Go 学习笔记 - Go 基础语法(2)

go 基础语法 (程序结构控制)

条件语句

  1. if
    1. if的条件里是不需要括号的
    2. if 的条件里可以赋值
    3. if 条件里赋值的变量作用于就在这个 if 语句里面
      func readsfile() {
       const filename = "abc.txt" // 注意创建文件
       // 写法1 比较多
       // go 语言的函数是可以返回两个值的
       countents, err := ioutil.ReadFile(filename)
       if err != nil {
           fmt.Print(err)
       } else {
           fmt.Printf("%s\n", countents)
       }
       // 写法2 if可以跟多个语句
       if countents, err := ioutil.ReadFile(filename); err != nil {
           fmt.Print(err)
       } else {
           fmt.Printf("%s\n", countents)
       }
      }
  2. switch
    1. switch 会自动 break, 除非使用 fallthrough
    2. switch 后可以没有表达式
    3. panic 会自动报错
      func grade(score int) string {
       g := ""
       switch {
       case score < 0 || score > 100:
           panic(fmt.Sprintf(
               "Wrong scor: %d", score))
       case score < 60:
           g = "F"
       case score < 80:
           g = "C"
       case score < 90:
           g = "B"
       case score <= 100:
           g = "A"
           // default:
           //     panic(fmt.Sprintf("Wrong scor: %d", score))
       }
       return g
      }
      // 函数入口
      func main() {
       fmt.Println(
           grade(0),
           grade(20),
           grade(50),
           grade(69),
           grade(98),
           grade(100),
           // grade(101),  // grade 报错不会返回前面的已经运算的结果,是直接跳出err
       )
      }

循环

  1. for

    1. for 的条件里不需要括号

    2. for 的条件里面可以省略初始条件,结束条件,递增表达式

    3. 省略初始条件相当于while, go 语言中没有 while

    4. 省略所有条件就是死循环

      func converToBin(n int) string {
        // 省略初始条件
        result := ""
        for ; n > 0; n /= 2 {
            lsb := n % 2
            result = strconv.Itoa(lsb) + result
        }
        return result
      }
      
      func printFile(filename string) {
        file, err := os.Open(filename)
        if err != nil {
            panic(err)
        }
        scanner := bufio.NewScanner(file)
        // 省略递增条件,省略初始条件,只有结束条件
        // 相当于while, go 语言中没有while
        for scanner.Scan() {
            fmt.Println(scanner.Text())
        }
      }
      
      func forever(){
        // 省略所有条件就是死循环
        // 死循环设计的这么好写是因为 go 中死循环使用的频率很高
        for {
            fmt.Println("hello")
        }
      }
      
      // 函数入口
      func main() {
        fmt.Println(
            converToBin(5),
            converToBin(13),
            converToBin(23333),
            converToBin(0),
        )
        printFile("abc.txt")
        forever()    
      }

函数

  1. 函数格式 func eval(a, b int, op string) int 函数名在前 类型在后

  2. 函数可以返回多个值

  3. 函数返回多个值可以起名(起名适用于非常简单的函数),对于调用者而言没有区别

     func eval(a, b int, op string) (int, error) {
         switch op {
         case "+":
             return a + b, nil
         case "-":
             return a - b, nil
         case "*":
             return a * b, nil
         case "/":
             return a / b, nil
         default:
             // 函数的多返回值不要乱用,一般是一个返回值,加一个 err
             // panic("unsupported operation:" + op)  // panic 直接报错中断程序,不建议使用
             return 0, fmt.Errorf("unsupported operation: %s", op)
         }
     }
    
     // 取余
     func div(a, b int) (q, r int) {
         // q,r 方便他人理解,返回值可以取个名字
         return a / b, a % b
    
         // 但是如果函数体过长,使用这这方法来 return 看起来会很累
         // q = a / b
         // r = a % b
         // return
     }
    
     // 函数入口
     func main() {
         fmt.Println(eval(3, 4, "*"))
         if result, err := eval(2, 3, "x"); err != nil {
             fmt.Printf("Error:", err)
         } else {
             fmt.Println(result)
         }
         // fmt.Println(div(13, 4))
         q, r := div(13, 4)
         s, _ := div(13, 4) // go 语言定义的变量一定要使用到,两个返回的变量就可以使用 _ 跳过不需要的返回值
         fmt.Println(q, r, s)
     }
  4. 函数式编程:函数的条件,参数包括函数内都可以嵌套函数

     // 简化上面的方法,不需要那么复杂的switch
     func apply(op func(int, int) int, a, b int) int {
         return op(a, b)
     }
    
     // 定义一个函数不需要再去转换浮点
     func pow(a, b int) int {
         return int(math.Pow(float64(a), float64(b)))
     }
    
     // 函数入口
     func main() {
         fmt.Println(apply(pow, 2, 4))
         // 如果觉得定义一个包比较麻烦,也可以直接写一个匿名函
         fmt.Println(apply(
             func(a, b int) int {
                 return int(math.Pow(float64(a), float64(b)))
             }, 2, 4))
     }
  5. go 语言函数没有默认参数,可选参数,参数重载.
    只有一个可变参数列表

     // ...int 代表随意传多少个int都可以
     func sum(numbers ...int) int {
         s := 0
         for i := range numbers {
             s += numbers[i]
         }
         return s
     }
    
     // 函数入口
     func main() {
         fmt.Println(sum(1, 2, 3, 4, 5)) // 15
     }

指针

  1. go 的指针不能运算
  2. go 只有值传递一种方式
    (值传递:拷贝,原函数中的值不会变. 引用传递:会改变原函数中的值)
    Go 学习笔记 - Go 基础语法(2)(值传递)
    Go 学习笔记 - Go 基础语法(2)(通过指针+值传递实现引用传递的效果)

Go 学习笔记 - Go 基础语法(2)

(object 的传递)

  1. 例子

     func swap(a, b *int) {
         *a, *b = *b, *a
     }
    
     // 函数入口
     func main() {
         a, b := 3, 4
         swap(&a, &b)
         fmt.Println(a, b)
     }
本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!