Golang的结构体类型struct

作者:matrix 发布时间:2023 年 6 月 24 日 分类:Golang

熟悉面向对象语言的话,Golangstruct结构体有点像面向对象编程中的。但这两者不是完全一样,只能说都有继承、封装、多态的特点。

结构体(struct)

结构体可以将零个或多个任意类型的值聚合在一起,能描述多个数据类型

type Person struct {
  name    string
  age     int
  value   string
  address string
}

成员方法和接收者

func (p *Person) setName(name string) {
  p.name = name
}

说明:
setName 为声明的方法
p *Person为接收者(指针类型)

struc类型新增成员方法的语法很另类,像是单独给struct做绑定,绑定的时候会有接收者来指定当前实例类型。

Golang其实可以给任何类型创建成员方法:

type MyInt int
func (i MyInt) IsZero() bool{
  return i == 0
}

这里通过声明int的自定义类型MyInt,然后绑定一个成员方法。灵活~

值接收者 指针接收者

方法的接收者可以是结构体的值或者指针。上面例子的接收者是一个Person类型的指针。指针接收者的一个优点是可以直接修改接收者的字段值,还避免值的拷贝(内部实际上是拷贝的指针)。

声明为值接收者也是可以:

func (p Person) getName() string {
  return p.name
}

getName方法会在调用时复制接收者,就可能会导致性能问题。一般是建议使用指针作为接收者

小结

值接收者或者指针接收者 都能调用结构体或者内嵌结构体的方法或者属性。
给结构体绑定成员方法时,参数最好使用指针,防止值拷贝

func (this *Person) setName(name string) 


// 申明结构体struct
type Person struct {
  name    string
  age     int
  value   string
  address string
}

//结构绑定

// 给结构体绑定成员方法。 不推荐使用,内存利用低效(参数会使用值传递,会内存拷贝)
//p Person这里p表示值接收者
// func (p Person) getName() string {
// 这里的p变量指针和外部调用的mPerson不同,这里属于值拷贝!!!
//  return p.name
// }

// 给Person结构体指针绑定成员方法,同上面效果。但是参数属于引用传递
//this为指针接收者
func (this *Person) getName() string {
  return this.name
}

// 给Person结构体指针绑定方法
func (this *Person) setName(name string) {
  this.name = name
}

func main() {
  //创建实例
  // var mPerson *Person = new(Person)//返回实例指针
  // var mPerson Person = *new(Person)//返回实例
  // var mPerson Person = Person{}//返回实例
  var mPerson *Person = &Person{name: "Hi~"} //获取实例指针
  mPerson.setName("")
  fmt.Println(mPerson.getName())
}

GitHub Action自动release发布版本 + docker镜像打包

作者:matrix 发布时间:2023 年 6 月 23 日 分类:零零星星

https://github.com/Hootrix/keyword_alert_bot

针对keyword_alert_bot项目早就有添加docker镜像的想法,这次趁着有机会就完成这个feature,也算是使用下GitHub的CI/CD。

我的想法是利用github action功能,推送代码更新后自动打包docker镜像且安装所有依赖。打包的时候把最新版本号写入到代码中(当前日期作为版本号)。使用者把docker镜像pull后可以轻松运行整个bot。

流水线配置

项目的 .github/workflows/main.yml路径下新建文件:

name: CI/CD Pipeline

on:
  push:

    # 指定分支push操作触发流水线
    branches:
      # - dev.20230419 # debug
      - master

jobs:

  # 自定义job流水线名字
  build-and-push:

    # 指定运行环境 ubuntu最新版本
    runs-on: ubuntu-latest

    # 设计流水线阶段
    steps:

    # 名称
    - name: Check out code
      # 使用预先定义好的action。actions/checkout@v2 是 GitHub 官方提供,目的是将代码检出(checkout)到运行器上
      uses: actions/checkout@v2
      with: # 配置参数
        fetch-depth: 2 # 表示只获取最新的两个commit提交记录 

    # 设置python3.7环境
    - name: Set up Python 3.7
      uses: actions/setup-python@v3
      with:
        python-version: 3.7

    # 安装pipenv依赖管理
    - name: Install pipenv
      run: |
        python -m pip install --upgrade pip
        python -m pip install pipenv

    # 标记是否存在py文件的更新,用于后续docker镜像打包的判断
    - name: Check for file changes
      id: file_check
      run: |
        if git diff --name-only HEAD^ | grep -q ".py$"; then
          echo "::set-output name=updated::true"
        else
          echo "::set-output name=updated::false"
        fi

    # 安装项目依赖
    - name: Install dependencies and lock
      if: steps.file_check.outputs.updated == 'true'
      run: |
        pipenv install --dev
        pipenv lock

    # 设置最新版本号 如 20230520.91a4ca1
    - name: Create version file
      run: |
        COMMIT_ID=$(git rev-parse --short HEAD)
        # 写入版本信息到指定文件 
        echo "__version__ = '$(TZ='Asia/Shanghai' date +'%Y%m%d').$COMMIT_ID'" > utils/__version__.py


    # 登录DockerHub
    - name: Login to DockerHub
      uses: docker/login-action@v1 
      with:
        username: ${{ secrets.DOCKER_HUB_USERNAME }}
        password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}

    # 存在更新条件 则推送到指定docker镜像仓库 tag为latest
    - name: Build and push Docker image
      if: steps.file_check.outputs.updated == 'true'
      uses: docker/build-push-action@v2
      with:
        context: .
        push: true

        # 推送到指定仓库镜像地址
        tags: yha8897/keyword_alert_bot:latest

    # 使用gh命令创建github release 执行版本发布
    - name: Create release
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      run: |
        # 读取指定文件的版本号。根据自己项目设置
        VERSION=$(python -c "from utils.__version__ import __version__; print(__version__)")
        echo $VERSION
        # 执行版本发布
        gh release create $VERSION

说明:

注意上面配置中的${{ secrets.DOCKER_HUB_USERNAME }},${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} 表示github action自动读取环境变量中的DOCKER_HUB_USERNAME,DOCKER_HUB_ACCESS_TOKEN 即 docker hub的登录名和密码

DOCKER_HUB_ACCESS_TOKEN 需要自己生成>>,权限设置Read & Write即可。

之后打开github项目页面的settings >> Secrets and variables >> Actions >> New repository secret按钮

TOKEN配置

New repository secret

New repository secret

填写你的docker hub的对应值。

secret list

${{ secrets.GITHUB_TOKEN }} 属于特殊环境变量(GITHUB_开头的都算),会自动读取你账户运行的权限,不需要自己单独设置。

触发流水线

配置完成后,提交或者合入代码到上面👆「branches」指定的master分支就能自动出发CI/CD

触发流水线

docker镜像会自动推送

参考:

https://raw.githubusercontent.com/Hootrix/keyword_alert_bot/master/.github/workflows/main.yml

https://docs.github.com/zh/actions/using-workflows/using-github-cli-in-workflows

https://zhuanlan.zhihu.com/p/526696611