专栏首页小码农漫漫积累路Go-函数高级使用-条件分支-包管理-for循环-switch语句-数组及切片-与或非逻辑符

Go-函数高级使用-条件分支-包管理-for循环-switch语句-数组及切片-与或非逻辑符

科普 python 注释 #

为什么几乎就 python 中的注释是 # ?

  • 起初 python 在 linux 中用的最多,linux 中大量的配置、shell 脚本等都是 # 作为注释的,所以 python 的注释也就沿用了 #

代码几乎都要写在 main 函数里执行(本文写的都是伪代码) 本文仅是跟着视频学习做的笔记,并未花时间去校对,如有错误,别太当真 重复定义是错误的,我的代码里有很多重复定义,只是为了写出来,你 copy 过去用的时候记得把重复定义删掉

函数高级

内层函数:定义在函数内部的函数

闭包函数:定义在函数内部,对外部作用域有引用(闭包函数本质也是内层函数)

  • go 中函数内部定义的函数是不能有名的,需要定义匿名函数:没有名字

在 go 语言中没有像 python 中的装饰器语法糖,但可以自己实现类似功能

// 内层函数
func test(a int) (func()) {
    // var c int = 100
    b := func() {
        fmt.println("我是内层函数(定义在了函数内部,但没有引用外部作用域)")
    }
}

// 闭包函数
func test(a int) (func()) {
    // var c int = 100
    b := func() {
        fmt.println(a)  // 是闭包函数,本身也是内层函数
    }
}


// 模仿 python 装饰器的写法
// 定义一个函数,传入函数,返回函数
func test(a func()) func()  {
    b:= func() {
        fmt.Println("我先执行")
        a()
        fmt.Println("函数执行完了")
    }
    return b
}

func test2()  {
    fmt.Println("xxxx")
}

func main() {
    a := test2
    a = test(a)
    a()
    //我先执行
    //xxxx
    //函数执行完了
}

给类型取别名 type MyFunc func(a, b int) func()

取了别名之后,用了别名的变量和原来的类型不是同一个类型了

// 给类型命别名
func main() {
    type MyInt int
    var a MyInt = 10
    var b int = 90
    // a = b  // 会报错,类型不匹配
    a = MyInt(b)  // 强转成一个类型
    fmt.Println(a)
    // 90
}


// 用在函数上面来简化写法
type MyFunc func(a int,b int) func()

type MyInt int
func test() (MyFunc)  {
    c:= func(a int,b int) func(){
        return func() {
            
        }
    }
    return c
}
func main() {
    var a MyInt=10
    var b int =90
    a=MyInt(b)
    fmt.Println(a)
    // 90
}

if else if else

跟 js 的写法差不多

  • if 条件 { 三个之间不能有换行(所有语言每一句结束都应该有一个 ;,很多语言都做了封装),如果加了换行,go 会自动在条件后面加上 ;,那么语义就错了
  • 在条件中可以定义变量,但是它的作用域范围只在 if 判断内部使用
package main

import "fmt"

func main() {
    if a := 90; a > 90 {
        fmt.Println("a>90")
    } else if a > 70 {
        fmt.Println("a>70")
    } else {
        fmt.Println(a)
    }
}
//a>70

包管理

go 的包管理一直被人所诟病(go 还是一门比较年轻的语言,需要时间来成长)

1)通常情况下,包名就是文件夹,在同一个文件夹下的 go 文件,文件里的包名必须一致

2)同一个包下定义的东西(变量、常量、函数)不能重名

  • 下面的两个文件同在 mypackage 包下(里面写的 package),所以第二次写 test 函数时,goland 编辑器就直接报错了

3)在包内定义的函数如果是小写字母开头,表示只能在包内使用(外部无法引用)

  • 要想在外部使用,必须首字母大写(函数定义的时候) package main import "fmt" import "mypackage" func main() { mypackage.Test1() fmt.Println("xxx") }

4)go 里导包只能导到包名那一层,不能说导里面的方法属性这些(import 包名

下载第三方包

go 是一个开源的社区语言,所以并没有 python 那样一个专门的 pipy 来下载模块镜像,都是去各个地方下载

go get github.com/astaxie/beego(地址)

比较热门的框架

  • beego 是中国人写的,所以官网文档也是中文的
  • gin 是外国人写的

go 的优点之一

  • go 写小接口很快,也很简单,部署也非常方便(微服务可能比 flask 写起来还要快)

可以了解一下 Supervisord(beego 官网文档里有)

  • 是一个用python写的进程管理工具
  • 由于 beego 的作者之一是 Python 的忠实拥护者之一,所以 orm 设计沿用了 django 的 orm

for 循环

for 循环的几种写法

// 不能重复定义,这里面的代码只是案例
package main

import "fmt"

func main() {
    // 基础写法
    for i := 0; i < 10; i++ {
        fmt.Println(i)
    }

    // 三部分都可以省略
    i := 0
    for ; i < 10; i++ {
        fmt.Println(i)
    }

    i := 0
    // for ;i<10; {  // 或
    for i < 10 { // 等同于 python 里的 while 循环 --> while True ==》 for True
        fmt.Println(i)
        i++
    }

    // 死循环
    // for ;; {  // 或
    for {
        fmt.Println("xxx")
    }

    // 注意下作用域范围(循环里定义的变量只能在循环里用)

    // --------中断或跳过本次循环--------
    // 用的是 break 和 continue,和其他语言的用法是一样的

    for i := 0; i < 10; i++ {
        if i == 5 {
            break
        }
        fmt.Println(i)
    }
    for i := 0; i < 10; i++ {
        if i == 5 {
            continue
        }
        fmt.Println(i)
    }

}

switch 语句

package main

import "fmt"

func main() {
    //a := 10
    //switch a {
    //case 1:
    //  fmt.Println("1")
    //case 2, 3, 4:
    //  fmt.Println("2-4")
    //  fallthrough // 只要读到这个,会无条件执行下面一个 case 内容
    //case 5:
    //  fmt.Println("5,a 是 2-4时顺带执行我")
    //default: // 都不匹配,会执行这个
    //  fmt.Println("都不是")
    //}
    ////都不是

    // 无表达式的 switch
    a := 10
    switch {
    case a > 10:
        fmt.Println("a大于10")
    case a < 10:
        fmt.Println("a小于10")
    default:
        fmt.Println("a等于10")
    }
    // a等于10
}

数组及数组切片

  • 数组是同一类型元素的集合
  • 在定义阶段,长度和类型就固定了,以后不能更改(这和 python 的列表有很大的区别)
  • 数组不支持负数索引
// 不能重复定义,这里面的代码只是案例
package main
import "fmt"

func main() {
    var a [5] int // 定义了一个长度为5的 int 类型数组
    fmt.Println(a)
    // [0 0 0 0 0]

    a[1] = 100 // 索引是从 0 开始的
    fmt.Println(a)
    // [0 100 0 0 0]

    // 定义并赋初值
    var a [6]int = [6]int{1,2,3,4,5,6}
    var a = [6]int{1,2,3}  // int 类型省略的几个自动用 0 填充
    
    a := [100]int{98:99} // 把第99个(索引是98)设置成99
    a := [100]int{1,2,3,98:99,87:88}
    // 不支持负数索引

}
  • 数组是值类型,所有函数传参都是 copy 传递(即 python 中的不可变类型)
package main
import "fmt"

func main() {
    a := [4]int{1,2,3}
    test7(a)
    fmt.Println(a)
}

func test7(b [4]int)  {
    b[0]=100
    fmt.Println(b)
}

// [100 2 3 0]
// [1 2 3 0]

go 1.5版本之前都是用C写的,但后面就开始用go语言写了

  • 数组的大小也是类型的一部分
// a 和 b 不是同一个类型
var a [4]int
var b [5]int
// 不同类型无法直接赋值,也无法直接做大小比较

数组迭代

package main
import "fmt"

func main() {
    var a [4]int = [4]int{1,2,}
    for i:=0;i<len(a);i++{  // len 可以获取数组长度
        fmt.Println(a[i])
    }
    //1
    //2
    //0
    //0

    // 通过 range 迭代(range是一个关键字)
    for i, v := range a {  // for 索引,值 range 可迭代对象
        fmt.Println("-----", i)  // 索引
        fmt.Println(v)  // 值
    }
    //----- 0
    //1
    //----- 1
    //2
    //----- 2
    //0
    //----- 3
    //0

    for i := range a {  // 一个值就是索引
        fmt.Println("-----", i)
    }
    //----- 0
    //----- 1
    //----- 2
    //----- 3
}

多维数组

package main
import "fmt"

func main() {
    var a [7][2]int
    fmt.Println(a)
    // [[0 0] [0 0] [0 0] [0 0] [0 0] [0 0] [0 0]]

    a[0][1]=100
    fmt.Println(a)
    // [[0 100] [0 0] [0 0] [0 0] [0 0] [0 0] [0 0]]]
}

与或非 && || !

package main
import "fmt"
func main() {
    a := 13
    if !(a < 1 && a > 0 || a == 6) {
        fmt.Println("success.")
        // success.
    }
}

作业

  1. 写一个闭包函数
  2. 定义一个包,内部写一个test函数,只给包内部用,写一个Test1函数,给外部包用,在main包内调用
  3. 使用go语言打印99乘法表
  4. 定义一个长度为100的数组,初始化前5个值都为8,第66个值为66
  5. 通过两种方式循环打印出上面的数组
  6. 将上面的数组的数据倒序放在另一个100长的数组中

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Go-常识补充-切片-map(类似字典)-字符串-指针-结构体

    fmt.Printf("%T", a) ,注意,用的是 fmt.Printf 函数,a 指的是要查看类型的变量

    suwanbin
  • MySQL-存储引擎-创建表-字段数据类型-严格模式-字段约束-键-02

    因为 InnoDB 在存储数据的时候,更加安全,所以默认的存储引擎是InnoDB(虽然 MyISAM 比 InnoDB 快)

    suwanbin
  • drf-更新四大接口-单改整体-单改局部-群改整体-群改局部-04

    suwanbin
  • 10.Go-goroutine,waitgroup,互斥锁,channel和select

    互斥锁表示锁的代码同一时间只能有一个goroutine运行,而读写锁表示在锁范围内数据的读写操作

    zhang_derek
  • Golang之匿名函数和闭包

     基本概念 闭包是可以包含自由(未绑定到特定对象)变量的代码块,这些变量不在这个代码块内或者 任何全局上下文中定义,而是在定义代码块的环境中定义。要执行的代码块...

    超蛋lhy
  • GoLang语言--的函数运用

    首先要学习一下go 语言的变量定义等等 我把代码copy一下 package mainimport ("fmt") type Books struct{ ...

    李海彬
  • 第二章、Go-基础语法

    zhang_derek
  • golang-指针

    landv
  • golang技术点整理

    defer的执行次序(先进后出)和执行的点(return之前, 返回值赋值之后)。

    王磊-AI基础
  • golang之数组

    3.长度是数组类型的一部分,因此,var a[5] int 和 var a[10]int 是不同的类型

    超蛋lhy

扫码关注云+社区

领取腾讯云代金券