├── .github ├── FUNDING.yml └── workflows │ └── ci.yml ├── .gitignore ├── LICENSE ├── README.md ├── example ├── array │ └── array.go ├── byte │ └── byte.go ├── const │ └── const.go ├── defer │ └── defer.go ├── float │ └── float.go ├── func │ └── func.go ├── hello │ └── hello.go ├── inteface │ └── inteface.go ├── iota │ └── iota.go ├── module │ ├── README.md │ ├── go.mod │ ├── go.sum │ └── main.go ├── package-demo │ ├── cal │ │ ├── add.go │ │ ├── multi │ │ │ └── multiply.go │ │ └── subtract.go │ └── main.go ├── print │ └── print1.go └── structs │ └── structs_fields.go ├── idoc.yml ├── package.json └── renovate.json /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | ko_fi: jaywcjlove 2 | buy_me_a_coffee: jaywcjlove 3 | custom: ["https://www.paypal.me/kennyiseeyou", "https://jaywcjlove.github.io/#/sponsor"] 4 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | on: 3 | push: 4 | branches: 5 | - master 6 | 7 | jobs: 8 | website: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v4 12 | - uses: actions/setup-node@v4 13 | with: 14 | node-version: 20 15 | registry-url: 'https://registry.npmjs.org' 16 | 17 | - run: npm install 18 | - run: npm run build 19 | - run: mkdir -p dist dist/example 20 | - run: cp -rp example dist/example 21 | # - run: npm i markdown-to-html-cli -g 22 | # - run: markdown-to-html --output build/index.html 23 | 24 | - name: Generate Contributors Images 25 | uses: jaywcjlove/github-action-contributors@main 26 | with: 27 | filter-author: (renovate\[bot\]|renovate-bot|dependabot\[bot\]) 28 | output: dist/CONTRIBUTORS.svg 29 | avatarSize: 42 30 | 31 | - name: Create Tag 32 | id: create_tag 33 | uses: jaywcjlove/create-tag-action@main 34 | with: 35 | package-path: ./package.json 36 | 37 | - name: get tag version 38 | id: tag_version 39 | uses: jaywcjlove/changelog-generator@main 40 | 41 | - name: Deploy 42 | uses: peaceiris/actions-gh-pages@v4 43 | with: 44 | user_name: 'github-actions[bot]' 45 | user_email: 'github-actions[bot]@users.noreply.github.com' 46 | commit_message: ${{steps.tag_version.outputs.tag}} ${{ github.event.head_commit.message }} 47 | github_token: ${{ secrets.GITHUB_TOKEN }} 48 | publish_dir: ./dist 49 | 50 | - name: Generate Changelog 51 | id: changelog 52 | uses: jaywcjlove/changelog-generator@main 53 | with: 54 | token: ${{ secrets.GITHUB_TOKEN }} 55 | filter-author: (jaywcjlove|小弟调调™|dependabot\[bot\]|Renovate Bot) 56 | filter: (^[\s]+?[R|r]elease)|(^[R|r]elease) 57 | 58 | - name: Create Release 59 | uses: ncipollo/release-action@v1 60 | if: steps.create_tag.outputs.successful 61 | with: 62 | allowUpdates: true 63 | token: ${{ secrets.GITHUB_TOKEN }} 64 | name: ${{ steps.create_tag.outputs.version }} 65 | tag: ${{ steps.create_tag.outputs.version }} 66 | body: | 67 | [![Buy me a coffee](https://img.shields.io/badge/Buy%20me%20a%20coffee-048754?logo=buymeacoffee)](https://jaywcjlove.github.io/#/sponsor) 68 | 69 | Documentation ${{ steps.changelog.outputs.tag }}: https://raw.githack.com/jaywcjlove/golang-tutorial/${{ steps.changelog.outputs.gh-pages-short-hash }}/index.html 70 | Comparing Changes: ${{ steps.changelog.outputs.compareurl }} 71 | 72 | ${{ steps.changelog.outputs.changelog }} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | test/out 4 | 5 | npm-debug.log* 6 | lerna-debug.log 7 | yarn-error.log 8 | package-lock.json 9 | 10 | .DS_Store 11 | .cache 12 | .vscode 13 | .idea 14 | 15 | *.bak 16 | *.tem 17 | *.temp 18 | #.swp 19 | *.*~ 20 | ~*.* 21 | 22 | # IDEA 23 | *.iml 24 | *.ipr 25 | *.iws 26 | .idea/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 小弟调调™ 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | Go语言快速入门 3 | === 4 | 5 | 6 | [![Buy me a coffee](https://img.shields.io/badge/Buy%20me%20a%20coffee-048754?logo=buymeacoffee)](https://jaywcjlove.github.io/#/sponsor) 7 | [![CI](https://github.com/jaywcjlove/golang-tutorial/actions/workflows/ci.yml/badge.svg)](https://github.com/jaywcjlove/golang-tutorial/actions/workflows/ci.yml) 8 | ![golang v1.18.3](https://img.shields.io/static/v1?label=&message=Golang%201.18.3&color=blue&logo=go&logoColor=white) 9 | 10 | 通过简单的例子,来快速入门Go语言基础编程、语法等各种语言特性,主要面向新手级别的学习者。下面所有例子均来源于网络,看文需谨慎后果自负。 11 | 12 | 安装之前需要了解及新建几个必要的文件目录: 13 | 14 | - GOROOT 目录,该目录为解压压缩包所存放的目录。 15 | >(建议 linux 环境解压到 /usr/local 目录,windows 环境解压到 C:\ProgramFiles 目录) 16 | - 新建 GOPATH 目录,即为我们的“工作目录”,该目录可以有多个,建议只设置一个。 17 | - GOPATH 目录下新建 `src` 目录,该目录用于存放第三方库源码,以及存放我们的项目的源码。 18 | - GOPATH 目录下新建 `bin` 目录,该目录用于存放项目中所生成的可执行文件。 19 | - GOPATH 目录下新建 `pkg` 目录,该目录用于存放编译生成的库文件。 20 | 21 | 22 | 23 | 目录 24 | --- 25 | 26 | - [安装Go](#安装go) 27 | - [卸载Go](#卸载go) 28 | - [运行Go](#运行go) 29 | - [格式化输入输出](#格式化输入输出) 30 | - [编程基础](#编程基础) 31 | - [基本类型](#基本类型) 32 | - [常量变量](#常量变量) 33 | - [语言运算符](#语言运算符) 34 | - [流程控制语句](#流程控制语句) 35 | - [结构体](#结构体) 36 | - [资源导航](#资源导航) 37 | 38 | 39 | 40 | ## 安装Go 41 | 42 | ### CentOS7 中通过 yum 安装 43 | 44 | ```bash 45 | # CentOS7 可以只用使用yum安装 46 | yum install golang 47 | ``` 48 | 49 | ### CentOS7 中通过源码安装 50 | 51 | ```bash 52 | # 源码下载 53 | # 官网源码 https://golang.org/dl/ 需要翻墙 54 | wget https://storage.googleapis.com/golang/go1.18.3.linux-amd64.tar.gz 55 | $ rm -rf /usr/local/go && tar -C /usr/local -xzf go1.18.3.linux-amd64.tar.gz 56 | ``` 57 | 58 | ```bash 59 | export PATH=$PATH:/usr/local/go/bin 60 | ``` 61 | 62 | ### Mac中通过brew命令安装 63 | 64 | 使用[home brew](http://brew.sh/)安装方便快捷安装Go,如果你想要在你的 Mac 系统上安装 Go,则必须使用 `Intel 64` 位处理器,Go 不支持 `PowerPC` 处理器。 65 | 66 | ```bash 67 | brew update && brew upgrade # 更新 Homebrew 的信息 68 | brew update go # 单独更新 golang 69 | brew install git # 安装 git 70 | brew install go # 安装 go 71 | brew upgrade go # 更新 go 72 | ``` 73 | 74 | ### Mac中通过源码安装 75 | 76 | 通过源代码编译安装的过程与环境变量的配置与在 Linux 系统非常相似,因此不再赘述。 77 | 78 | **注意事项:** 79 | 80 | 在 Mac 系统下使用到的 C 工具链是 Xcode 的一部分,因此你需要通过安装 Xcode 来完成这些工具的安装。你并不需要安装完整的 Xcode,而只需要安装它的命令行工具部分。 81 | 82 | ### 环境变量配置 83 | 84 | 通过`go env`查看go的详细信息 85 | 86 | ```bash 87 | → go env 88 | 89 | GO111MODULE="" 90 | GOARCH="arm64" 91 | GOBIN="" 92 | GOCACHE="/Users/wangchujiang/Library/Caches/go-build" 93 | GOENV="/Users/wangchujiang/Library/Application Support/go/env" 94 | GOEXE="" 95 | GOEXPERIMENT="" 96 | GOFLAGS="" 97 | GOHOSTARCH="arm64" 98 | GOHOSTOS="darwin" 99 | GOINSECURE="" 100 | GOMODCACHE="/Users/wangchujiang/go/pkg/mod" 101 | GONOPROXY="" 102 | GONOSUMDB="" 103 | GOOS="darwin" 104 | GOPATH="/Users/wangchujiang/go" 105 | GOPRIVATE="" 106 | GOPROXY="https://proxy.golang.org,direct" 107 | GOROOT="/usr/local/go" 108 | GOSUMDB="sum.golang.org" 109 | GOTMPDIR="" 110 | GOTOOLDIR="/usr/local/go/pkg/tool/darwin_arm64" 111 | GOVCS="" 112 | GOVERSION="go1.18.3" 113 | GCCGO="gccgo" 114 | AR="ar" 115 | CC="clang" 116 | CXX="clang++" 117 | CGO_ENABLED="1" 118 | GOMOD="/dev/null" 119 | GOWORK="" 120 | CGO_CFLAGS="-g -O2" 121 | CGO_CPPFLAGS="" 122 | CGO_CXXFLAGS="-g -O2" 123 | CGO_FFLAGS="-g -O2" 124 | CGO_LDFLAGS="-g -O2" 125 | PKG_CONFIG="pkg-config" 126 | GOGCCFLAGS="-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/rn/jv6_kn5j2wv1whyj3pqvpxbw0000gn/T/go-build947462154=/tmp/go-build -gno-record-gcc-switches -fno-common" 127 | ``` 128 | 129 | 如果需要修改默认的环境变量配置修改 `vim ~/.bash_profile` 或者 `vim ~/.zshrc` 130 | 131 | ```bash 132 | #GOROOT 133 | # CentOS 中如下设置 GOROOT,看你安装的路径 134 | # export GOROOT=/usr/local/go 135 | # Mac OS 中通过命令行工具brew安装如下配置 GOROOT 136 | export GOROOT=/usr/local/Cellar/go/1.9/libexec 137 | #GOPATH root bin 138 | export GOBIN=$GOROOT/bin 139 | export PATH=$PATH:$GOBIN 140 | #GOPATH 141 | export GOPATH=$HOME/go 142 | #GOPATH bin 143 | export PATH=$PATH:$GOPATH/bin 144 | ``` 145 | 146 | 使其立即生效 147 | 148 | ```bash 149 | source /etc/profile 150 | ``` 151 | 152 | ### 标准命令详解 153 | 154 | ```bash 155 | → go --help 156 | 157 | Go 是一个管理 Go 源代码的工具。 158 | 159 | 用法: 160 | 161 | go [arguments] 162 | 163 | 命令是: 164 | 165 | bug 开始一个错误报告。 start a bug report 166 | build 编译包和依赖。 compile packages and dependencies 167 | clean 删除目标文件和缓存文件。 remove object files and cached files 168 | doc 显示包或符号的文档。 show documentation for package or symbol 169 | env 打印Go环境信息。 print Go environment information 170 | fix 更新软件包以使用新的 API。 update packages to use new APIs 171 | fmt gofmt(重新格式化)包源。 gofmt (reformat) package sources 172 | generate 通过处理源生成 Go 文件。 generate Go files by processing source 173 | get 将依赖项添加到当前模块并安装它们。 add dependencies to current module and install them 174 | install 编译和安装包和依赖项。 compile and install packages and dependencies 175 | list 列出包或模块。 list packages or modules 176 | mod 模块维护。 module maintenance 177 | work 工作空间维护。 workspace maintenance 178 | run 编译并运行 Go 程序。 compile and run Go program 179 | test 测试包。 test packages 180 | tool 运行指定的 go 工具。 run specified go tool 181 | version 打印 Go 版本。 print Go version 182 | vet 报告包中可能出现的错误。 report likely mistakes in packages 183 | 184 | 使用“go help ”获取有关命令的更多信息。 185 | 186 | 其他帮助主题: 187 | 188 | buildconstraint 构建约束。 build constraints 189 | buildmode 构建模式。 build modes 190 | c Go 和 C 之间的调用。 calling between Go and C 191 | cache 构建和测试缓存。 build and test caching 192 | environment 环境变量。 environment variables 193 | filetype 文件类型。 file types 194 | go.mod go.mod 文件。 the go.mod file 195 | gopath GOPATH 环境变量。 GOPATH environment variable 196 | gopath-get 遗留的 GOPATH 去获取。 legacy GOPATH go get 197 | goproxy 模块代理协议。 module proxy protocol 198 | importpath 导入路径语法。 import path syntax 199 | modules 模块、模块版本等。 modules, module versions, and more 200 | module-get 模块感知 go get。 module-aware go get 201 | module-auth 使用 go.sum 进行模块认证。 module authentication using go.sum 202 | packages 包装清单和模式。 package lists and patterns 203 | private 下载非公开代码的配置。 configuration for downloading non-public code 204 | testflag 测试标志。 testing flags 205 | testfunc 测试功能。 testing functions 206 | vcs 使用 GOVCS 控制版本控制。 controlling version control with GOVCS 207 | 208 | Use "go help " for more information about that topic. 209 | ``` 210 | 211 | 其它命令 212 | 213 | ```bash 214 | cat $GOROOT/VERSION # 查看版本 215 | $GOROOT/src/all.bash # 测试用例正确 216 | ``` 217 | 218 | ### 依赖管理工具 219 | 220 | 目前 Go 语言常用的依赖管理工具,有三个 [godep](https://github.com/tools/godep)、[vendor](https://github.com/kardianos/govendor)和[db](https://github.com/constabulary/gb/),`vendor` 是go 1.5 官方引入管理包依赖的方式,1.6正式引入。所以这里推荐是用[vendor](https://github.com/kardianos/govendor)来管理你的依赖。 221 | 222 | 快速开始: 223 | 224 | ```bash 225 | # 设置你的项目 226 | cd "my project in GOPATH" 227 | govendor init 228 | 229 | # 将现有的GOPATH文件添加到vendor。 230 | govendor add +external 231 | 232 | # 查看你的工作。 233 | govendor list 234 | 235 | govendor sync # 从远程仓库拉取依赖 236 | govendor get # 像“go get”一样,但将依赖项复制到“vendor”文件夹中。 237 | 238 | # 看看什么是使用包 239 | govendor list -v fmt 240 | 241 | # 指定要获取的特定版本或修订版本 242 | govendor fetch golang.org/x/net/context@a4bbce9fcae005b22ae5443f6af064d80a6f5a55 243 | govendor fetch golang.org/x/net/context@v1 # Get latest v1.*.* tag or branch. 244 | govendor fetch golang.org/x/net/context@=v1 # Get the tag or branch named "v1". 245 | 246 | # 给予任何先前版本的约束,将包更新为最新 247 | govendor fetch golang.org/x/net/context 248 | 249 | # 仅格式化您的存储库 250 | govendor fmt +local 251 | 252 | # 构建您的存储库中的所有内容 253 | govendor install +local 254 | 255 | # 仅测试您的存储库 256 | govendor test +local 257 | ``` 258 | 259 | ## 卸载go 260 | 261 | - 删除 Go 的安装文件目录,这通常是在 `Linux`,`macOS` 和 `FreeBSD` 下的 `/usr/local/` go 或者在 Windows 下的 `c:\Go` 下。 262 | - 同时删除环境变量, `Linux` 和 `FreeBSD` 编辑 `/etc/profile` 或者 `$HOME/.profile`。 263 | - 如果你是 `macOS` 你需要删除 `/etc/paths.d/go`,`/usr/local/go` 文件。 264 | 265 | ## 运行Go 266 | 267 | ### 运行Go文档,在线预览文档 268 | 269 | ```bash 270 | # 如果你的 godoc 命令不存在,运行它安装 271 | $ go get -v golang.org/x/tools/cmd/godoc 272 | 273 | $ godoc -http=:6060 274 | # 运行上面一条命令,可访问文档http://localhost:6060/ 275 | ``` 276 | 277 | ### 通过go命令运行 278 | 279 | 我们先写一段GO代码,很简单就是打印输出一个`hello world!`, 保存为[hello.go](./example/hello/hello.go)文件 280 | 281 | ```go 282 | package main 283 | import "fmt" 284 | func main() { 285 | fmt.Println("Hello, World!") 286 | } 287 | ``` 288 | 289 | 命令运行`go`程序,在[hello.go](./example/hello/hello.go)这个当前目录下运行下面命令,可以输出`hello world!`。 290 | 291 | ```bash 292 | go run hello.go 293 | ``` 294 | 295 | ### 通过go命令编译运行 296 | 297 | GO程序的代码是可以直接编译成`exe文件` 或者 `二进制文件`直接运行,在[hello.go](./example/hello/hello.go)目录下运行下面命令,即可把go程序编译成二进制文件 298 | 299 | ```bash 300 | go build hello.go 301 | ``` 302 | 303 | 上面命令文件可以编译成一个`hello`可执行文件,然后直接在当前目录下 `./hello` 运行,可以输出`hello world!`。 304 | 305 | ### 在浏览器中运行 306 | 307 | Go Playground 允许在浏览器里面编辑运行 Go 语言代码。在浏览器中打开 https://play.golang.org/ (需要穿越才能打开) ,输入代码,点击 Run,看看会发生什么?还有个 Share 按钮,点击它会得到一个用于分享的网址,任何人都能代开这个链接,试一试 https://play.golang.org/p/UIOwu0DBQV 308 | 309 | ## 格式化输入输出 310 | 311 | ### 输入输出语法方法 312 | 313 | > `%[标记][宽度][.精度][arg索引]动词` 314 | > `Print(arg列表)`、`Println(arg列表)`、`Printf(格式字符串, arg列表)` 315 | 316 | ```go 317 | package main 318 | import ( 319 | "fmt" 320 | "time" 321 | ) 322 | func main() { 323 | fmt.Println("Hello World!") 324 | fmt.Println("The time is", time.Now()) 325 | } 326 | ``` 327 | 328 | ### 标记 329 | 330 | ``` 331 | + 总打印数值的正负号;对于%q(%+q)保证只输出ASCII编码的字符。 332 | - 在右侧而非左侧填充空格(左对齐该区域) 333 | # 备用格式:为八进制添加前导 0(%#o),为十六进制添加前导 0x(%#x)或 334 | 0X(%#X),为 %p(%#p)去掉前导 0x;对于 %q,若 strconv.CanBackquote 335 | 返回 true,就会打印原始(即反引号围绕的)字符串;如果是可打印字符, 336 | %U(%#U)会写出该字符的Unicode编码形式(如字符 x 会被打印成 U+0078 'x')。 337 | ' ' (空格)为数值中省略的正负号留出空白(% d); 338 | 以十六进制(% x, % X)打印字符串或切片时,在字节之间用空格隔开 339 | 0 填充前导的0而非空格;对于数字,这会将填充移到正负号之后 340 | ``` 341 | 342 | - 其中 `0` 和 `-` 不能同时使用,优先使用 `-` 而忽略 `0`。 343 | - 标记有时会被占位符忽略,所以不要指望它们。例如十进制没有备用格式,因此 `%#d` 与 `%d` 的行为相同。 344 | 345 | ### 宽度和精度 346 | 347 | `[宽度][.精度]`都可以写成以下三种形式:`数值`,`*`,`arg索引*` 348 | 349 | - `数值` 表示使用指定的数值作为宽度值或精度值 350 | - `*` 表示使用当前正在处理的 arg 的值作为宽度值或精度值,如果这样的话,要格式化的 arg 将自动跳转到下一个。 351 | - `arg索引*` 表示使用指定 arg 的值作为宽度值或精度值,如果这样的话,要格式化的 arg 将自动跳转到指定 arg 的下一个。 352 | 353 | 注意事项: 354 | 355 | - 宽度值:用于设置最小宽度。 356 | - 精度值:对于浮点型,用于控制小数位数,对于字符串或字节数组,用于控制字符数量(不是字节数量)。 357 | - 对于浮点型而言,动词 g/G 的精度值比较特殊,在适当的情况下,g/G 会设置总有效数字,而不是小数位数。 358 | 359 | ### arg 索引 360 | 361 | 由中括号和 arg 序号组成(就像这个实例`"abc%+ #8.3[3]vdef"`中的[3]),用于指定当前要处理的 arg 的序号,序号从 1 开始:`'[' + arg序号 + ']'` 362 | 363 | ### 动词/通用动词 364 | 365 | - `v`:默认格式,不同类型的默认格式如下: 366 | > 布尔型:`t` 367 | > 整 型:`d` 368 | > 浮点型:`g` 369 | > 复数型:`g` 370 | > 字符串:`s` 371 | > 通 道:`p` 372 | > 指 针:`p` 373 | 374 | - `#v`:默认格式,以符合 Go 语法的方式输出。特殊类型的 Go 语法格式如下: 375 | > 无符号整型:x 376 | - `T`:输出 arg 的类型而不是值(使用 Go 语法格式)。 377 | 378 | 注意事项:`动词`不能省略,不同的数据类型支持的动词不一样。 379 | 380 | ### 布尔型 381 | 382 | -`t` :输出 true 或 false 字符串。 383 | 384 | ### 整型 385 | 386 | - `b/o/d`:输出 2/8/10 进制格式 387 | - `x/X `:输出 16 进制格式(小写/大写) 388 | - `c `:输出数值所表示的 Unicode 字符 389 | - `q `:输出数值所表示的 Unicode 字符(带单引号)。对于无法显示的字符,将输出其转义字符。 390 | - `U `:输出 Unicode 码点(例如 U+1234,等同于字符串 "U+%04X" 的显示结果) 391 | 392 | 对于 o/x/X: 393 | - 如果使用 "#" 标记,则会添加前导 0 或 0x。 394 | 395 | 对于 U: 396 | - 如果使用 "#" 标记,则会在 Unicode 码点后面添加相应的 '字符'(前提是该字符必须可显示) 397 | 398 | ### 浮点型和复数型 399 | 400 | - `b`:科学计数法(以 2 为底) 401 | - `e/E`:科学计数法(以 10 为底,小写 e/大写 E) 402 | - `f/F`:普通小数格式(两者无区别) 403 | - `g/G`:大指数(指数 >= 6)使用 %e/%E,其它情况使用 %f/%F 404 | 405 | ### 字符串或字节切片 406 | 407 | - `s` :普通字符串 408 | - `q` :双引号引起来的 Go 语法字符串 409 | - `x/X`:十六进制编码(小写/大写,以字节为元素进行编码,而不是字符) 410 | 411 | 对于 q: 412 | - 如果使用了 `+` 标记,则将所有非 ASCII 字符都进行转义处理。 413 | - 如果使用了 `#` 标记,则输出反引号引起来的字符串(前提是 414 | - 字符串中不包含任何制表符以外的控制字符,否则忽略 # 标记) 415 | 416 | 对于 x/X: 417 | - 如果使用了 " " 标记,则在每个元素之间添加空格。 418 | - 如果使用了 "#" 标记,则在十六进制格式之前添加 0x 前缀。 419 | 420 | ### 指针类型 421 | 422 | - `p` :带 0x 前缀的十六进制地址值。 423 | - `#p`:不带 0x 前缀的十六进制地址值。 424 | - Go 没有指针运算。 425 | 426 | Go 具有指针。 指针保存了变量的内存地址。 427 | 428 | 类型 *T 是指向类型 T 的值的指针。其零值是 nil 。 429 | 430 | ```go 431 | var p *int 432 | ``` 433 | 434 | & 符号会生成一个指向其作用对象的指针。 435 | 436 | ```go 437 | i := 42 438 | p = &i 439 | ``` 440 | 441 | * 符号表示指针指向的底层的值。 442 | 443 | ```go 444 | fmt.Println(*p) // 通过指针 p 读取 i 445 | *p = 21 // 通过指针 p 设置 i 446 | ``` 447 | 448 | 这也就是通常所说的“间接引用”或“非直接引用”。 449 | 450 | ```go 451 | package main 452 | import "fmt" 453 | func main() { 454 | i, j := 42, 2701 455 | p := &i // 指向我 i 456 | fmt.Println(*p) // 通过指针读 i 457 | *p = 21 // 通过指针设置 i 458 | fmt.Println(i) // 看到i的新值 459 | 460 | p = &j // 指向我 j 461 | *p = *p / 37 // 通过指针划分 j 462 | fmt.Println(j) // 看到j的新值 463 | } 464 | ``` 465 | 466 | ### 复合类型 467 | 468 | 复合类型将使用不同的格式输出,格式如下: 469 | 470 | ``` 471 | 结 构 体:{字段1 字段2 ...} 472 | 数组或切片:[元素0 元素1 ...] 473 | 映   射:map[键1:值1 键2:值2 ...] 474 | ``` 475 | 476 | 指向复合元素的指针:`&{}`, `&[]`, `&map[]` 477 | 复合类型本身没有动词,动词将应用到复合类型的元素上。 478 | 结构体可以使用 "+v" 同时输出字段名。 479 | 480 | ### 格式化输入 481 | 482 | ```go 483 | // 格式化输入:从输入端读取字符串(以空白分隔的值的序列), 484 | // 并解析为具体的值存入相应的 arg 中,arg 必须是变量地址。 485 | // 字符串中的连续空白视为单个空白,换行符根据不同情况处理。 486 | // \r\n 被当做 \n 处理。 487 | 488 | // 以动词 v 解析字符串,换行视为空白 489 | Scan(arg列表) 490 | // 以动词 v 解析字符串,换行结束解析 491 | Scanln(arg列表) 492 | // 根据格式字符串中指定的格式解析字符串 493 | // 格式字符串中的换行符必须和输入端的换行符相匹配。 494 | Scanf(格式字符串, arg列表) 495 | 496 | // Scan 类函数会返回已处理的 arg 数量和遇到的错误信息。 497 | ``` 498 | 499 | ## 编程基础 500 | 501 | ### 内置关键字 502 | 503 | ```go 504 | break default func interface select 505 | case defer go map struct 506 | chan else goto package switch 507 | const fallthrough if range type 508 | continue for import return var 509 | ``` 510 | 511 | ### 预定义标识符 512 | 513 | ```go 514 | append bool byte cap close complex complex64 complex128 uint16 515 | copy false float32 float64 imag int int8 int16 uint32 516 | int32 int64 iota len make new nil panic uint64 517 | print println real recover string true uint uint8 uintptr 518 | ``` 519 | 520 | ### 行分隔符 521 | 522 | - 在 Go 程序中,一行代表一个语句结束,不需要分隔符。 523 | - 打算将多个语句写在同一行,它们则必须使用 `;` 人为区分,并不鼓励这种做法。 524 | 525 | ### 注释方法 526 | 527 | ```go 528 | // 单行注释 529 | 530 | /* 531 | 多行注释 532 | */ 533 | ``` 534 | 535 | ### 标识符 536 | 537 | - 标识符用来命名变量、类型等程序实体。 538 | - 第一个字符必须是字母或下划线而不能是数字 539 | 540 | 有效标识符 541 | 542 | ``` 543 | mahesh kumar abc move_name a_123 544 | myname50 _temp j a23b9 retVal 545 | ``` 546 | 547 | 无效标识符 548 | 549 | ```bash 550 | 1ab #(以数字开头) 551 | case #(Go 语言的关键字) 552 | a+b #(运算符是不允许的) 553 | ``` 554 | 555 | ### 包引用 import 556 | 557 | ```go 558 | import "fmt" 559 | import "os" 560 | import "io" 561 | ``` 562 | 563 | 简写方式如下 564 | 565 | ```go 566 | import ( 567 | "fmt" 568 | "os" 569 | "io" 570 | ) 571 | ``` 572 | 573 | **包引用介绍** 574 | 575 | ```bash 576 | . 577 | ├── cal 578 | │   ├── add.go 579 | │   ├── multi 580 | │   │   └── multiply.go 581 | │   └── subtract.go 582 | └── main.go 583 | ``` 584 | 585 | 注意:[package-demo](example/package-demo) 文件夹复制到 `$GOPATH/src/` 目录下,不然运行报错哦 586 | 587 | ```bash 588 | go run $GOPATH/src/package-demo/main.go 589 | ``` 590 | 591 | main.go中如何调用add.go、subtract.go或者是multiply.go文件中的函数。 592 | 593 | > `add.go`和`subtract.go`文件中,包名为cal `package cal` 594 | > `multiply.go`在 multi 文件夹下,所以程序的包名为multi `package multi` 595 | > 如果 mian 函数要调用`add.go`或者`subtract.go`中的函数,必须要引入包"cal" `import "package-demo/cal"` 596 | > 要调用`multiply.go`中的函数,必须要引入包"multi",`import "package-demo/cal/multi"` 597 | > Go中如果函数名的首字母大写,表示该函数是公有的,可以被其他程序调用,如果首字母小写,该函数就是是私有的 598 | 599 | ### 包别名 600 | 601 | ```go 602 | import( 603 | ff "fmt" 604 | ) 605 | 606 | // 或者 607 | import ff "fmt" 608 | 609 | // 别名包调用 610 | ff.Println('Hello World!') 611 | ``` 612 | 613 | ### 省略调用 614 | 615 | ```go 616 | import( 617 | . "fmt" 618 | ) 619 | func main() { 620 | // 省略调用 621 | Println('Hello World!') 622 | } 623 | ``` 624 | 625 | ### 可见性规则 626 | 627 | Go语言中约定使用 **大小写** 来决定常量、变量、类型、接口、结构或函数是否可以被外部包所调用 628 | 629 | - 函数名字首字母 **小写** 即为 `private` 私有的 630 | - 函数名字首字母 **大写** 即为 `public` 公有 631 | 632 | ## 基本类型 633 | 634 | ### 布尔型 635 | 636 | ```go 637 | var b bool 638 | b = true 639 | fmt.Printf("b is of type %t\n", b) 640 | e := bool(true) 641 | fmt.Printf("e is of type %t\n", e) 642 | ``` 643 | 644 | - 长度:1字节 645 | - 取值范围:true/false 646 | - 只能使用true/false值,不能使用数字代替布尔值 647 | 648 | ### 整形 int/uint 649 | 650 | ```go 651 | package main 652 | import "fmt" 653 | func main() { 654 | // n 是一个长度为 10 的数组 655 | var n [10]int 656 | var i,j int 657 | 658 | /* 为数组 n 初始化元素 */ 659 | for i = 0; i < 10; i++ { 660 | n[i] = i + 100 /* 设置元素为 i + 100 */ 661 | } 662 | 663 | /* 输出每个数组元素的值 */ 664 | for j = 0; j < 10; j++ { 665 | fmt.Printf("Element[%d] = %d\n", j, n[j] ) 666 | } 667 | } 668 | ``` 669 | 670 | - int/uint 671 | - 根据平台可能为32/64位 672 | 673 | ### 8位整型 int8/uint8 674 | 675 | ```go 676 | u8 := []uint8{98, 99} 677 | 678 | a := byte(255) //11111111 这是byte的极限, 因为 a := byte(256)//越界报错, 0~255正好256个数,不能再高了 679 | b := uint8(255) //11111111 这是uint8的极限,因为 c := uint8(256)//越界报错,0~255正好256个数,不能再高了 680 | c := int8(127) //01111111 这是int8的极限, 因为 b := int8(128)//越界报错, 0~127正好128个数,所以int8的极限只是256的一半 681 | d := int8(a) //11111111 打印出来则是-0000001,int8(128)、int8(255)、int8(byte(255))都报错越界,因为int极限是127,但是却可以写:int8(a),第一位拿来当符号了 682 | e := int8(c) //01111111 打印出来还是01111111 683 | fmt.Printf("%08b %d \n", a, a) 684 | fmt.Printf("%08b %d \n", b, b) 685 | fmt.Printf("%08b %d \n", c, c) 686 | fmt.Printf("%08b %d \n", d, d) 687 | fmt.Printf("%08b %d \n", e, e) 688 | ``` 689 | 690 | - int8/uint8 691 | - 长度:1字节 692 | - 取值范围:-128~127/0~255 693 | 694 | ### 字节型 byte 695 | 696 | ```go 697 | // 这里不能写成 b := []byte{"Golang"},这里是利用类型转换。 698 | b := []byte("Golang") 699 | c := []byte("go") 700 | d := []byte("Go") 701 | println(b,c,d) 702 | ``` 703 | 704 | - byte(uint8别名) 705 | 706 | **基本处理函数** 707 | 708 | - `Contains()` 返回是否包含子切片 709 | - `Count()` 子切片非重叠实例的数量 710 | - `Map()` 函数,将byte 转化为Unicode,然后进行替换 711 | - `Repeat()` 将切片复制count此,返回这个新的切片 712 | - `Replace()` 将切片中的一部分 替换为另外的一部分 713 | - `Runes()` 将 S 转化为对应的 UTF-8 编码的字节序列,并且返回对应的Unicode 切片 714 | - `Join()` 函数,将子字节切片连接到一起。 715 | 716 | 可以参考下面列子来理解上面7个方法,例子 [byte.go](./example/byte/byte.go) 717 | 718 | ```go 719 | package main 720 | import ( 721 | "bytes" 722 | "fmt" 723 | ) 724 | func main() { 725 | // 这里不能写成 b := []byte{"Golang"},这里是利用类型转换。 726 | b := []byte("Golang") 727 | subslice1 := []byte("go") 728 | subslice2 := []byte("Go") 729 | // func Contains(b, subslice [] byte) bool 730 | // 检查字节切片b ,是否包含子字节切片 subslice 731 | fmt.Println(bytes.Contains(b, subslice1)) 732 | fmt.Println(bytes.Contains(b, subslice2)) 733 | 734 | 735 | s2 := []byte("同学们,上午好") 736 | m := func(r rune) rune { 737 | if r == '上' { 738 | r = '下' 739 | } 740 | return r 741 | } 742 | fmt.Println(string(s2)) 743 | // func Map(mapping func(r rune) rune, s []byte) []byte 744 | // Map函数: 首先将 s 转化为 UTF-8编码的字符序列, 745 | // 然后使用 mapping 将每个Unicode字符映射为对应的字符, 746 | // 最后将结果保存在一个新的字节切片中。 747 | fmt.Println(string(bytes.Map(m, s2))) 748 | 749 | 750 | s3 := []byte("google") 751 | old := []byte("o") 752 | //这里 new 是一个字节切片,不是关键字了 753 | new := []byte("oo") 754 | n := 1 755 | // func Replace(s, old, new []byte, n int) []byte 756 | //返回字节切片 S 的一个副本, 并且将前n个不重叠的子切片 old 替换为 new,如果n < 0 那么不限制替换的数量 757 | fmt.Println(string(bytes.Replace(s3, old, new, n))) 758 | fmt.Println(string(bytes.Replace(s3, old, new, -1))) 759 | 760 | 761 | // 将字节切片 转化为对应的 UTF-8编码的字节序列,并且返回对应的 Unicode 切片。 762 | s4 := []byte("中华人民共和国") 763 | r1 := bytes.Runes(s4) 764 | // func Runes(b []byte) []rune 765 | fmt.Println(string(s4), len(s4)) // 字节切片的长度 766 | fmt.Println(string(r1), len(r1)) // rune 切片的长度 767 | 768 | 769 | // 字节切片 的每个元素,依旧是字节切片。 770 | s5 := [][]byte{ 771 | []byte("你好"), 772 | []byte("世界"), //这里的逗号,必不可少 773 | } 774 | sep := []byte(",") 775 | // func Join(s [][]byte, sep []byte) []byte 776 | // 用字节切片 sep 吧 s中的每个字节切片连接成一个,并且返回. 777 | fmt.Println(string(bytes.Join(s5, sep))) 778 | } 779 | ``` 780 | 781 | ### 16位整型 int16/uint16 782 | 783 | - int16/uint16 784 | - 长度:2字节 785 | - 取值范围:-32768~32767/0~65535 786 | 787 | ### 32位整型 int32(别名rune)/uint32 788 | 789 | - int32(别名rune)/uint32 790 | - 长度:4字节 791 | - 取值范围:-2^32/2~2^32/2-1/0~2^32-1 792 | 793 | ### 64位整型 int64/uint64 794 | 795 | - int64/uint64 796 | - 长度:8字节 797 | - 取值范围:-2^64/2~2^64/2-1/0~2^64-1 798 | 799 | ### 浮点型 float32/float64 800 | 801 | ```go 802 | package main 803 | import "fmt" 804 | 805 | func main() { 806 | var x float64 807 | x = 20.0 808 | fmt.Println(x) 809 | fmt.Printf("x is of type %T\n", x) 810 | 811 | a := float64(20.0) 812 | b := 42 813 | fmt.Println(a) 814 | fmt.Println(b) 815 | fmt.Printf("a is of type %T\n", a) 816 | fmt.Printf("b is of type %T\n", b) 817 | } 818 | ``` 819 | 820 | 实例:[float.go](./example/float/float.go) 821 | 822 | - float32/float64 823 | - 长度:4/8字节 824 | - 小数位:精确到 7/15 位小数 825 | 826 | ### 复数 complex64/complex128 827 | 828 | - complex64/complex128 829 | - 长度:8/16 830 | 831 | ### 指针整数型 uintptr 832 | 833 | 用于指针运算,GC 不把 uintptr 当指针,uintptr 无法持有对象。uintptr 类型的目标会被回收。 834 | 835 | - uintptr 836 | - 保存指正的 32 位或者 64 位整数型 837 | 838 | ```go 839 | // 示例:通过指针修改结构体字段 840 | package main 841 | import ( 842 | "fmt" 843 | "unsafe" 844 | ) 845 | 846 | func main() { 847 | s := struct { 848 | a byte 849 | b byte 850 | c byte 851 | d int64 852 | }{0, 0, 0, 0} 853 | 854 | // 将结构体指针转换为通用指针 855 | p := unsafe.Pointer(&s) 856 | // 保存结构体的地址备用(偏移量为 0) 857 | up0 := uintptr(p) 858 | // 将通用指针转换为 byte 型指针 859 | pb := (*byte)(p) 860 | // 给转换后的指针赋值 861 | *pb = 10 862 | // 结构体内容跟着改变 863 | fmt.Println(s) 864 | 865 | // 偏移到第 2 个字段 866 | up := up0 + unsafe.Offsetof(s.b) 867 | // 将偏移后的地址转换为通用指针 868 | p = unsafe.Pointer(up) 869 | // 将通用指针转换为 byte 型指针 870 | pb = (*byte)(p) 871 | // 给转换后的指针赋值 872 | *pb = 20 873 | // 结构体内容跟着改变 874 | fmt.Println(s) 875 | 876 | // 偏移到第 3 个字段 877 | up = up0 + unsafe.Offsetof(s.c) 878 | // 将偏移后的地址转换为通用指针 879 | p = unsafe.Pointer(up) 880 | // 将通用指针转换为 byte 型指针 881 | pb = (*byte)(p) 882 | // 给转换后的指针赋值 883 | *pb = 30 884 | // 结构体内容跟着改变 885 | fmt.Println(s) 886 | 887 | // 偏移到第 4 个字段 888 | up = up0 + unsafe.Offsetof(s.d) 889 | // 将偏移后的地址转换为通用指针 890 | p = unsafe.Pointer(up) 891 | // 将通用指针转换为 int64 型指针 892 | pi := (*int64)(p) 893 | // 给转换后的指针赋值 894 | *pi = 40 895 | // 结构体内容跟着改变 896 | fmt.Println(s) 897 | } 898 | ``` 899 | 900 | ### 数组类型 array 901 | 902 | 数组声明语法 903 | 904 | ```go 905 | var variable_name [SIZE]variable_type 906 | ``` 907 | 908 | 数组是具有相同唯一类型的一组已编号且长度固定的数据项序列,这种类型可以是任意的原始类型例如整形、字符串或者自定义类型。下面是一个简单的对数组操作的例子[array.go](./example/array/array.go) 909 | 910 | ```go 911 | package main 912 | import "fmt" 913 | func main() { 914 | // 声明一个长度为5的整数数组 915 | // 一旦数组被声明了,那么它的数据类型跟长度都不能再被改变。 916 | var array1 [5]int 917 | 918 | fmt.Printf("array1: %d\n\n", array1) 919 | 920 | // 声明一个长度为5的整数数组 921 | // 初始化每个元素 922 | array2 := [5]int{12, 123, 1234, 12345, 123456} 923 | array2[1] = 5000 924 | fmt.Printf("array2: %d\n\n", array2[1]) 925 | 926 | // n 是一个长度为 10 的数组 927 | var n [10]int 928 | var i,j int 929 | 930 | /* 为数组 n 初始化元素 */ 931 | for i = 0; i < 10; i++ { 932 | n[i] = i + 100 /* 设置元素为 i + 100 */ 933 | } 934 | 935 | /* 输出每个数组元素的值 */ 936 | for j = 0; j < 10; j++ { 937 | fmt.Printf("Element[%d] = %d\n", j, n[j] ) 938 | } 939 | 940 | /* 数组 - 5 行 2 列*/ 941 | var a = [5][2]int{ {0,0}, {1,2}, {2,4}, {3,6},{4,8}} 942 | var e, f int 943 | 944 | /* 输出数组元素 */ 945 | for e = 0; e < 5; e++ { 946 | for f = 0; f < 2; f++ { 947 | fmt.Printf("a[%d][%d] = %d\n", e,f, a[e][f] ) 948 | } 949 | } 950 | } 951 | ``` 952 | 953 | 初始化数组中 {} 中的元素个数不能大于 [] 中的数字。 954 | 如果忽略 [] 中的数字不设置数组大小,Go 语言会根据元素的个数来设置数组的大小: 955 | 956 | ```go 957 | var array1 = [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0} 958 | ``` 959 | 960 | 数组元素可以通过索引(位置)来读取。格式为数组名后加中括号,中括号中为索引的值。例如: 961 | 962 | ```go 963 | float32 salary = array1[9] 964 | ``` 965 | 966 | 以上实例读取了数组`array1`第`10`个元素的值。 967 | 968 | 多维数组,下面例子 969 | 970 | ```go 971 | // 三行四列 972 | a = [3][4]int{ 973 | {0, 1, 2, 3} , /* 第一行索引为 0 */ 974 | {4, 5, 6, 7} , /* 第二行索引为 1 */ 975 | {8, 9, 10, 11} /* 第三行索引为 2 */ 976 | } 977 | ``` 978 | 979 | 访问多维数组 980 | 981 | ```go 982 | // 访问第2行第3列 983 | int val = a[2][3] 984 | ``` 985 | 986 | ### 结构类型 struct 987 | 988 | ```go 989 | package main 990 | import "fmt" 991 | type Vertex struct { 992 | X int 993 | Y int 994 | } 995 | func main() { 996 | fmt.Println(Vertex{1, 2}) 997 | 998 | // 结构体字段使用点号来访问。 999 | v := Vertex{1, 2} 1000 | v.X = 4 1001 | fmt.Println(v.X) 1002 | 1003 | // 结构体字段可以通过结构体指针来访问。 1004 | e := Vertex{1, 2} 1005 | p := &e 1006 | p.X = 1e9 1007 | fmt.Println(e) 1008 | 1009 | 1010 | var ( 1011 | v1 = Vertex{1, 2} // 类型为 Vertex 1012 | v2 = Vertex{X: 1} // Y:0 被省略 1013 | v3 = Vertex{} // X:0 和 Y:0 1014 | p = &Vertex{1, 2} // 类型为 *Vertex , 特殊的前缀 & 返回一个指向结构体的指针 1015 | ) 1016 | fmt.Println(v1, p, v2, v3) 1017 | } 1018 | ``` 1019 | 1020 | 简单的结构体 1021 | 1022 | ```go 1023 | type T struct {a, b int} 1024 | ``` 1025 | 1026 | 结构体里的字段都有 名字,像 `field1`、`field2` 等,如果字段在代码中从来也不会被用到,那么可以命名它为 `_`。上面简单的结构体定义,下面调用方法: 1027 | 1028 | ```go 1029 | var s T 1030 | s.a = 5 1031 | s.b = 8 1032 | ``` 1033 | 1034 | 数组可以看作是一种结构体类型,不过它使用下标而不是具名的字段。 1035 | 1036 | ```go 1037 | var t *T 1038 | t = new(T) 1039 | ``` 1040 | 1041 | 上面简单的管用语句方法`t := new(T)`,变量 `t` 是一个指向 `T` 的指针,此时结构体字段的值是它们所属类型的零值。 1042 | 1043 | 声明 `var t T` 也会给 `t` 分配内存,并零值化内存,但是这个时候 `t` 是类型`T`。在这两种方式中,`t` 通常被称做类型 `T` 的一个实例(instance)或对象(object)。 1044 | 1045 | 一个非常简单的例子[structs_fields.go](./example/structs/structs_fields.go)运行例子查看结果: 1046 | 1047 | ```bash 1048 | → go run test/structs_fields.go 1049 | 1050 | The int is: 10 1051 | The float is: 15.500000 1052 | The string is: Chris 1053 | &{10 15.5 Chris} 1054 | ``` 1055 | 1056 | **使用 new** 1057 | 1058 | ### 字符串类型 string 1059 | 1060 | ```go 1061 | var str string //声明一个字符串 1062 | str = "Go lang" //赋值 1063 | ch :=str[0] //获取第一个字符 1064 | len :=len(str) //字符串的长度,len是内置函数 ,len=5 1065 | ``` 1066 | 1067 | len函数是Go中内置函数,不引入strings包即可使用。len(string)返回的是字符串的字节数。len函数所支持的入参类型如下: 1068 | 1069 | - len(Array) 数组的元素个数 1070 | - len(*Array) 数组指针中的元素个数,如果入参为nil则返回0 1071 | - len(Slice) 数组切片中元素个数,如果入参为nil则返回0 1072 | - len(map) 字典中元素个数,如果入参为nil则返回0 1073 | - len(Channel) Channel buffer队列中元素个数 1074 | 1075 | ### 接口类型 inteface 1076 | 1077 | ```go 1078 | package main 1079 | import ( 1080 | "fmt" 1081 | "math" 1082 | ) 1083 | 1084 | /* 定义一个 interface */ 1085 | type shape interface { 1086 | area() float64 1087 | } 1088 | 1089 | /* 定义一个 circle */ 1090 | type circle struct { 1091 | x,y,radius float64 1092 | } 1093 | 1094 | /* 定义一个 rectangle */ 1095 | type rectangle struct { 1096 | width, height float64 1097 | } 1098 | 1099 | /* 定义一个circle方法 (实现 shape.area())*/ 1100 | func(circle circle) area() float64 { 1101 | return math.Pi * circle.radius * circle.radius 1102 | } 1103 | 1104 | /* 定义一个rectangle方法 (实现 shape.area())*/ 1105 | func(rect rectangle) area() float64 { 1106 | return rect.width * rect.height 1107 | } 1108 | 1109 | /* 定义一个shape的方法*/ 1110 | func getArea(shape shape) float64 { 1111 | return shape.area() 1112 | } 1113 | 1114 | func main() { 1115 | circle := circle{x:0,y:0,radius:5} 1116 | rectangle := rectangle {width:10, height:5} 1117 | 1118 | fmt.Printf("circle area: %f\n",getArea(circle)) 1119 | fmt.Printf("rectangle area: %f\n",getArea(rectangle)) 1120 | } 1121 | ``` 1122 | 1123 | 实例:[inteface.go](./example/inteface/inteface.go) 1124 | 1125 | ### 函数类型 func 1126 | 1127 | ```go 1128 | package main 1129 | import "fmt" 1130 | type functinTyoe func(int, int) // 声明了一个函数类型 1131 | func (f functinTyoe)Serve() { 1132 | fmt.Println("serve2") 1133 | } 1134 | func serve(int,int) { 1135 | fmt.Println("serve1") 1136 | } 1137 | func main() { 1138 | a := functinTyoe(serve) 1139 | a(1,2) 1140 | a.Serve() 1141 | } 1142 | ``` 1143 | 1144 | 实例:[func.go](./example/func/func.go) 1145 | 1146 | ### 引用类型 func 1147 | 1148 | **切片** 1149 | 1150 | > 是一种可以动态数组,可以按我们的希望增长和收缩。 1151 | 1152 | - slice 1153 | 1154 | **Map** 1155 | 1156 | > 是一种无序的键值对的集合。是一种集合,所以我们可以像迭代数组和 slice 那样迭代它。 1157 | 1158 | - map 1159 | 1160 | ```go 1161 | // 通过 make 来创建 1162 | dict := make(map[string]int) 1163 | // 通过字面值创建 1164 | dict := map[string]string{"Red": "#da1337", "Orange": "#e95a22"} 1165 | 1166 | // 给 map 赋值就是指定合法类型的键,然后把值赋给键 1167 | colors := map[string]string{} 1168 | colors["Red"] = "#da1337" 1169 | 1170 | // 不初始化 map , 就会创建一个 nil map。nil map 不能用来存放键值对,否则会报运行时错误 1171 | var colors map[string]string 1172 | colors["Red"] = "#da1337" 1173 | // Runtime Error: 1174 | // panic: runtime error: assignment to entry in nil map 1175 | 1176 | //选择是只返回值,然后判断是否是零值来确定键是否存在。 1177 | value := colors["Blue"] 1178 | if value != "" { 1179 | fmt.Println(value) 1180 | } 1181 | ``` 1182 | 1183 | 在函数间传递 map 不是传递 map 的拷贝。所以如果我们在函数中改变了 map,那么所有引用 map 的地方都会改变 1184 | 1185 | ```go 1186 | func main() { 1187 | colors := map[string]string{ 1188 | "AliceBlue": "#f0f8ff", 1189 | "Coral": "#ff7F50", 1190 | "DarkGray": "#a9a9a9", 1191 | "ForestGreen": "#228b22", 1192 | } 1193 | for key, value := range colors { 1194 | fmt.Printf("Key: %s Value: %s\n", key, value) 1195 | } 1196 | removeColor(colors, "Coral") 1197 | for key, value := range colors { 1198 | fmt.Printf("Key: %s Value: %s\n", key, value) 1199 | } 1200 | } 1201 | func removeColor(colors map[string]string, key string) { 1202 | delete(colors, key) 1203 | } 1204 | ``` 1205 | 1206 | 1207 | **通道** 1208 | 1209 | - chan 1210 | 1211 | ### 类型别名 1212 | 1213 | ```go 1214 | type ( 1215 | byte int8 1216 | rune init32 1217 | 文本 string 1218 | ) 1219 | var b 文本 1220 | b = "别名类型,可以是中文!" 1221 | ``` 1222 | 1223 | ## 常量变量 1224 | 1225 | ### 常量 const 1226 | 1227 | ```go 1228 | package main 1229 | import "unsafe" 1230 | // 常量可以用len(), cap(), unsafe.Sizeof()常量计算表达式的值。 1231 | // 常量表达式中,函数必须是内置函数,否则编译不过: 1232 | const ( 1233 | a = "abc" 1234 | b = len(a) 1235 | c = unsafe.Sizeof(a) 1236 | ) 1237 | 1238 | func main(){ 1239 | const ( 1240 | PI = 3.14 1241 | const1 = "1" 1242 | ) 1243 | const LENGTH int = 10 1244 | const e, f, g = 1, false, "str" //多重赋值 1245 | println(a, b, c,PI, LENGTH) 1246 | } 1247 | ``` 1248 | 1249 | 上面例子[const.go](./example/const/const.go) 1250 | 1251 | **iota** 特殊常量,可以认为是一个可以被编译器修改的常量。[iota.go](./example/iota/iota.go) 1252 | 1253 | ```go 1254 | package main 1255 | import "fmt" 1256 | func main() { 1257 | const ( 1258 | // 第一个 iota 等于 0,每当 iota 在新的一行被使用时,它的值都会自动加 1; 1259 | // 所以 a=0, b=1, c=2 可以简写为如下形式: 1260 | a = iota //0 1261 | b //1 1262 | c //2 1263 | d = "ha" //独立值,iota += 1 1264 | e //"ha" iota += 1 1265 | f = 100 //iota +=1 1266 | g //100 iota +=1 1267 | h = iota //7,恢复计数 1268 | i //8 1269 | ) 1270 | fmt.Println(a,b,c,d,e,f,g,h,i) 1271 | } 1272 | ``` 1273 | 1274 | ### 变量 var 1275 | 1276 | ```go 1277 | var ( 1278 | name = "gopher" 1279 | name1 = "1" 1280 | ) 1281 | // 变量声明 1282 | var a int 1283 | a = 11 /* 赋值 */ 1284 | 1285 | // 变量声明 并赋值 1286 | var b int = 12 1287 | 1288 | // 应用在函数体内的方式 1289 | var a, b, c, d int = 1, 2, 3, 4 1290 | // a =1 1291 | // b =2 1292 | // c =3 1293 | // d =4 1294 | 1295 | 1296 | var a, _, c, d int = 1, 2, 3, 4 1297 | // 忽略 _ 返回值忽略 1298 | ``` 1299 | 1300 | - 全局变量名 以大写开头 1301 | - 全局变量不可以省略 var ,可以使用并行的方式 1302 | - 所有变量都可以使用类型推断 1303 | - 局部变量不可以使用`var()`简写的形式 1304 | 1305 | ### 变量的类型转换 1306 | 1307 | ```go 1308 | // 只能类型显式转换 1309 | var a float32 = 1.1 1310 | // 省略var, 简短形式,使用 := 赋值操作符 1311 | b := int(a) 1312 | // 不兼容的类型不能转换类型 1313 | ``` 1314 | 1315 | ### 多变量声明 1316 | 1317 | ```go 1318 | var x, y int 1319 | // 这种因式分解关键字的写法一般用于声明全局变量 1320 | var ( 1321 | a int 1322 | b bool 1323 | ) 1324 | 1325 | var c, d int = 1, 2 1326 | var e, f = 123, "hello" 1327 | 1328 | //这种不带声明格式的只能在函数体中出现 1329 | //g, h := 123, "hello" 1330 | ``` 1331 | 1332 | ## 语言运算符 1333 | 1334 | ### 算术运算符 1335 | 1336 | ```go 1337 | package main 1338 | import "fmt" 1339 | func main() { 1340 | var a int = 21 1341 | var b int = 10 1342 | var c int 1343 | c = a + b 1344 | fmt.Printf("第一行 - c 的值为 %d\n", c ) // 第一行 - c 的值为 31 1345 | c = a - b 1346 | fmt.Printf("第二行 - c 的值为 %d\n", c ) // 第二行 - c 的值为 11 1347 | c = a * b 1348 | fmt.Printf("第三行 - c 的值为 %d\n", c ) // 第三行 - c 的值为 210 1349 | c = a / b 1350 | fmt.Printf("第四行 - c 的值为 %d\n", c ) // 第四行 - c 的值为 2 1351 | c = a % b 1352 | fmt.Printf("第五行 - c 的值为 %d\n", c ) // 第五行 - c 的值为 1 1353 | a++ 1354 | fmt.Printf("第六行 - a 的值为 %d\n", a ) // 第六行 - a 的值为 22 1355 | a-- 1356 | fmt.Printf("第七行 - a 的值为 %d\n", a ) // 第七行 - a 的值为 21 1357 | } 1358 | ``` 1359 | 1360 | 下表列出了所有Go语言的算术运算符。假定 A 值为 10,B 值为 20。 1361 | 1362 | | 运算符 | 描述 | 实例 | 1363 | | ---- | ---- | ---- | 1364 | | + | 相加 | A + B 输出结果 30 | 1365 | | - | 相减 | A - B 输出结果 -10 | 1366 | | * | 相乘 | A * B 输出结果 200 | 1367 | | / | 相除 | B / A 输出结果 2 | 1368 | | % | 求余 | B % A 输出结果 0 | 1369 | | ++ | 自增 | A++ 输出结果 11 | 1370 | | -- | 自减 | A-- 输出结果 9 | 1371 | 1372 | ### 关系运算符 1373 | 1374 | ```go 1375 | package main 1376 | import "fmt" 1377 | func main() { 1378 | var a int = 21 1379 | var b int = 10 1380 | if( a == b ) { 1381 | fmt.Printf("第一行 - a 等于 b\n" ) 1382 | } else { 1383 | fmt.Printf("第一行 - a 不等于 b\n" ) 1384 | } 1385 | if ( a < b ) { 1386 | fmt.Printf("第二行 - a 小于 b\n" ) 1387 | } else { 1388 | fmt.Printf("第二行 - a 不小于 b\n" ) 1389 | } 1390 | 1391 | if ( a > b ) { 1392 | fmt.Printf("第三行 - a 大于 b\n" ) 1393 | } else { 1394 | fmt.Printf("第三行 - a 不大于 b\n" ) 1395 | } 1396 | /* 让我们改变a和b的值 */ 1397 | a = 5 1398 | b = 20 1399 | if ( a <= b ) { 1400 | fmt.Printf("第四行 - a 小于等于 b\n" ) 1401 | } 1402 | if ( b >= a ) { 1403 | fmt.Printf("第五行 - b 大于等于 a\n" ) 1404 | } 1405 | } 1406 | ``` 1407 | 1408 | 下表列出了所有Go语言的关系运算符。假定 A 值为 10,B 值为 20。 1409 | 1410 | | 运算符 | 描述 | 实例 | 1411 | | ---- | ---- | ---- | 1412 | | == | 检查两个值是否相等,如果相等返回 True 否则返回 False。 | (A == B) 为 False | 1413 | | != | 检查两个值是否不相等,如果不相等返回 True 否则返回 False。 | (A != B) 为 True | 1414 | | > | 检查左边值是否大于右边值,如果是返回 True 否则返回 False。 | (A > B) 为 False | 1415 | | < | 检查左边值是否小于右边值,如果是返回 True 否则返回 False。 | (A < B) 为 True | 1416 | | >= | 检查左边值是否大于等于右边值,如果是返回 True 否则返回 False。 | (A >= B) 为 False | 1417 | | <= | 检查左边值是否小于等于右边值,如果是返回 True 否则返回 False。 | A <= B) 为 True | 1418 | 1419 | ### 逻辑运算符 1420 | 1421 | ```go 1422 | package main 1423 | import "fmt" 1424 | func main() { 1425 | var a bool = true 1426 | var b bool = false 1427 | if ( a && b ) { 1428 | fmt.Printf("第一行 - 条件为 true\n" ) 1429 | } 1430 | if ( a || b ) { 1431 | fmt.Printf("第二行 - 条件为 true\n" ) 1432 | } 1433 | /* 修改 a 和 b 的值 */ 1434 | a = false 1435 | b = true 1436 | if ( a && b ) { 1437 | fmt.Printf("第三行 - 条件为 true\n" ) 1438 | } else { 1439 | fmt.Printf("第三行 - 条件为 false\n" ) 1440 | } 1441 | if ( !(a && b) ) { 1442 | fmt.Printf("第四行 - 条件为 true\n" ) 1443 | } 1444 | } 1445 | ``` 1446 | 1447 | 下表列出了所有Go语言的逻辑运算符。假定 A 值为 `True`,B 值为 `False` d。 1448 | 1449 | | 运算符 | 描述 | 实例 | 1450 | | ---- | ---- | ---- | 1451 | | && | 逻辑 AND 运算符。 如果两边的操作数都是 True,则条件 True,否则为 False。 | (A && B) 为 False | 1452 | | \|\| | 逻辑 OR 运算符。 如果两边的操作数有一个 True,则条件 True,否则为 False。| (A || B) 为 True | 1453 | | ! | 逻辑 NOT 运算符。 如果条件为 True,则逻辑 NOT 条件 False,否则为 True。 | !(A && B) 为 True | 1454 | 1455 | ### 位运算符 1456 | 1457 | ```go 1458 | package main 1459 | import "fmt" 1460 | func main() { 1461 | 1462 | var a uint = 60 /* 60 = 0011 1100 */ 1463 | var b uint = 13 /* 13 = 0000 1101 */ 1464 | var c uint = 0 1465 | 1466 | c = a & b /* 12 = 0000 1100 */ 1467 | fmt.Printf("第一行 - c 的值为 %d\n", c ) // 第一行 - c 的值为 12 1468 | 1469 | c = a | b /* 61 = 0011 1101 */ 1470 | fmt.Printf("第二行 - c 的值为 %d\n", c ) // 第二行 - c 的值为 61 1471 | 1472 | c = a ^ b /* 49 = 0011 0001 */ 1473 | fmt.Printf("第三行 - c 的值为 %d\n", c ) // 第三行 - c 的值为 49 1474 | 1475 | c = a << 2 /* 240 = 1111 0000 */ 1476 | fmt.Printf("第四行 - c 的值为 %d\n", c ) // 第四行 - c 的值为 240 1477 | 1478 | c = a >> 2 /* 15 = 0000 1111 */ 1479 | fmt.Printf("第五行 - c 的值为 %d\n", c ) // 第五行 - c 的值为 15 1480 | } 1481 | ``` 1482 | 1483 | Go 语言支持的位运算符如下表所示。假定 A 为60,B 为13: 1484 | 1485 | | 运算符 | 描述 | 实例 | 1486 | | ---- | ---- | ---- | 1487 | | & | 按位与运算符"&"是双目运算符。 其功能是参与运算的两数各对应的二进位相与。 | (A & B) 结果为 12, 二进制为 0000 1100 | 1488 | | \| | 按位或运算符 \| 是双目运算符。 其功能是参与运算的两数各对应的二进位相或。 | (A \| B) 结果为 61, 二进制为 0011 1101 | 1489 | | ^ | 按位异或运算符"^"是双目运算符。 其功能是参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1。 | (A ^ B) 结果为 49, 二进制为 0011 0001 | 1490 | | << | 左移运算符"<<"是双目运算符。左移n位就是乘以2的n次方。 其功能把"<<"左边的运算数的各二进位全部左移若干位,由"<<"右边的数指定移动的位数,高位丢弃,低位补0。 | A << 2 结果为 240 ,二进制为 1111 0000 | 1491 | | >> | 右移运算符">>"是双目运算符。右移n位就是除以2的n次方。 其功能是把">>"左边的运算数的各二进位全部右移若干位,">>"右边的数指定移动的位数。| A >> 2 结果为 15 ,二进制为 0000 1111 | 1492 | 1493 | ### 赋值运算符 1494 | 1495 | ```go 1496 | package main 1497 | import "fmt" 1498 | func main() { 1499 | var a int = 21 1500 | var c int 1501 | 1502 | c = a 1503 | fmt.Printf("第 1 行 - = 运算符实例,c 值为 = %d\n", c ) 1504 | // 第 1 行 - = 运算符实例,c 值为 = 21 1505 | c += a 1506 | fmt.Printf("第 2 行 - += 运算符实例,c 值为 = %d\n", c ) 1507 | // 第 2 行 - += 运算符实例,c 值为 = 42 1508 | c -= a 1509 | fmt.Printf("第 3 行 - -= 运算符实例,c 值为 = %d\n", c ) 1510 | // 第 3 行 - -= 运算符实例,c 值为 = 21 1511 | c *= a 1512 | fmt.Printf("第 4 行 - *= 运算符实例,c 值为 = %d\n", c ) 1513 | // 第 4 行 - *= 运算符实例,c 值为 = 441 1514 | c /= a 1515 | fmt.Printf("第 5 行 - /= 运算符实例,c 值为 = %d\n", c ) 1516 | // 第 5 行 - /= 运算符实例,c 值为 = 21 1517 | c = 200; 1518 | c <<= 2 1519 | fmt.Printf("第 6 行 - <<= 运算符实例,c 值为 = %d\n", c ) 1520 | // 第 6 行 - <<= 运算符实例,c 值为 = 800 1521 | c >>= 2 1522 | fmt.Printf("第 7 行 - >>= 运算符实例,c 值为 = %d\n", c ) 1523 | // 第 7 行 - >>= 运算符实例,c 值为 = 200 1524 | c &= 2 1525 | fmt.Printf("第 8 行 - &= 运算符实例,c 值为 = %d\n", c ) 1526 | // 第 8 行 - &= 运算符实例,c 值为 = 0 1527 | c ^= 2 1528 | fmt.Printf("第 9 行 - ^= 运算符实例,c 值为 = %d\n", c ) 1529 | // 第 9 行 - ^= 运算符实例,c 值为 = 2 1530 | c |= 2 1531 | fmt.Printf("第 10 行 - |= 运算符实例,c 值为 = %d\n", c ) 1532 | // 第 10 行 - |= 运算符实例,c 值为 = 2 1533 | } 1534 | ``` 1535 | 1536 | | 运算符 | 描述 | 实例 | 1537 | | ---- | ---- | ---- | 1538 | | = | 简单的赋值运算符,将一个表达式的值赋给一个左值s | C = A + B 将 A + B 表达式结果赋值给 C | 1539 | | += | 相加后再赋值s | C += A 等于 C = C + A | 1540 | | -= | 相减后再赋值s | C -= A 等于 C = C - A | 1541 | | *= | 相乘后再赋值s | C *= A 等于 C = C * A | 1542 | | /= | 相除后再赋值s | C /= A 等于 C = C / A | 1543 | | %= | 求余后再赋值s | C %= A 等于 C = C % A | 1544 | | <<= | 左移后赋值s | C <<= 2 等于 C = C << 2 | 1545 | | >>= | 右移后赋值s | C >>= 2 等于 C = C >> 2 | 1546 | | &= | 按位与后赋值s | C &= 2 等于 C = C & 2 | 1547 | | ^= | 按位异或后赋值s | C ^= 2 等于 C = C ^ 2 | 1548 | | \|= | 按位或后赋值s | C \|= 2 等于 C = C \| 2 | 1549 | 1550 | ### 其他运算符 1551 | 1552 | ```go 1553 | package main 1554 | import "fmt" 1555 | func main() { 1556 | var a int = 4 1557 | var b int32 1558 | var c float32 1559 | var ptr *int 1560 | 1561 | /* 运算符实例 */ 1562 | fmt.Printf("第 1 行 - a 变量类型为 = %T\n", a ); // 第 1 行 - a 变量类型为 = int 1563 | fmt.Printf("第 2 行 - b 变量类型为 = %T\n", b ); // 第 2 行 - b 变量类型为 = int32 1564 | fmt.Printf("第 3 行 - c 变量类型为 = %T\n", c ); // 第 3 行 - c 变量类型为 = float32 1565 | 1566 | /* & 和 * 运算符实例 */ 1567 | ptr = &a /* 'ptr' 包含了 'a' 变量的地址 */ 1568 | fmt.Printf("a 的值为 %d\n", a); // a 的值为 4 1569 | fmt.Printf("*ptr 为 %d\n", *ptr); // *ptr 为 4 1570 | } 1571 | ``` 1572 | 1573 | | 运算符 | 描述 | 实例 | 1574 | | ---- | ---- | ---- | 1575 | | & | 返回变量存储地址 | &a; 将给出变量的实际地址。 | 1576 | | * | 指针变量。 | *a; 是一个指针变量 | 1577 | 1578 | ### 运算符优先级 1579 | 1580 | ```go 1581 | package main 1582 | import "fmt" 1583 | func main() { 1584 | var a int = 20 1585 | var b int = 10 1586 | var c int = 15 1587 | var d int = 5 1588 | var e int; 1589 | // 通过使用括号来临时提升某个表达式的整体运算优先级。 1590 | e = (a + b) * c / d; // ( 30 * 15 ) / 5 1591 | fmt.Printf("(a + b) * c / d 的值为 : %d\n", e ); 1592 | e = ((a + b) * c) / d; // (30 * 15 ) / 5 1593 | fmt.Printf("((a + b) * c) / d 的值为 : %d\n" , e ); 1594 | e = (a + b) * (c / d); // (30) * (15/5) 1595 | fmt.Printf("(a + b) * (c / d) 的值为 : %d\n", e ); 1596 | e = a + (b * c) / d; // 20 + (150/5) 1597 | fmt.Printf("a + (b * c) / d 的值为 : %d\n" , e ); 1598 | } 1599 | ``` 1600 | 1601 | 有些运算符拥有较高的优先级,二元运算符的运算方向均是从左至右。下表列出了所有运算符以及它们的优先级,由上至下代表优先级由高到低: 1602 | 1603 | | 优先级 | 运算符 | 1604 | | ---- | ---- | 1605 | | 7 | ^ ! | 1606 | | 6 | * / % << >> & &^ | 1607 | | 5 | + - \| ^ | 1608 | | 4 | == != < <= >= > | 1609 | | 3 | <- | 1610 | | 2 | && | 1611 | | 1 | \|\| | 1612 | 1613 | ## 流程控制语句 1614 | 1615 | ### for 循环语句 1616 | 1617 | ```go 1618 | package main 1619 | import "fmt" 1620 | func main() { 1621 | sum := 0 1622 | // 如果条件表达式的值变为 false,那么迭代将终止。 1623 | for i := 0; i < 10; i++ { 1624 | sum += i 1625 | } 1626 | fmt.Println(sum) 1627 | 1628 | // 循环初始化语句和后置语句都是可选的。 1629 | // for 是 Go 的 “while” 1630 | // 基于此可以省略分号:C 的 while 在 Go 中叫做 for 。 1631 | // 如果省略了循环条件,循环就不会结束,因此可以用更简洁地形式表达死循环。 1632 | sum2 := 1 1633 | for ; sum2 < 1000; { 1634 | sum2 += sum2 1635 | } 1636 | fmt.Println(sum2) 1637 | } 1638 | ``` 1639 | 基本的 for 循环包含三个由分号分开的组成部分: 1640 | 1641 | 1. 初始化语句:在第一次循环执行前被执行 1642 | 1. 循环条件表达式:每轮迭代开始前被求值 1643 | 1. 后置语句:每轮迭代后被执行 1644 | 1645 | ### if 语句 1646 | 1647 | ```go 1648 | package main 1649 | import ( 1650 | "fmt" 1651 | "math" 1652 | ) 1653 | func sqrt(x float64) string { 1654 | if x < 0 { 1655 | return sqrt(-x) + "i" 1656 | } 1657 | return fmt.Sprint(math.Sqrt(x)) 1658 | } 1659 | func main() { 1660 | fmt.Println(sqrt(2), sqrt(-4)) 1661 | } 1662 | ``` 1663 | 1664 | 就像 for 循环一样,Go 的 if 语句也不要求用 ( ) 将条件括起来,同时, { } 还是必须有的。 1665 | 1666 | **if 的便捷语句** 1667 | 1668 | ```go 1669 | package main 1670 | import ( 1671 | "fmt" 1672 | "math" 1673 | ) 1674 | 1675 | func pow(x, n, lim float64) float64 { 1676 | if v := math.Pow(x, n); v < lim { 1677 | return v 1678 | } 1679 | return lim 1680 | } 1681 | func main() { 1682 | fmt.Println( 1683 | pow(3, 2, 10), 1684 | pow(3, 3, 20), 1685 | ) 1686 | } 1687 | ``` 1688 | 1689 | ### if 和 else 语句 1690 | 1691 | ```go 1692 | package main 1693 | import ( 1694 | "fmt" 1695 | "math" 1696 | ) 1697 | func pow(x, n, lim float64) float64 { 1698 | if v := math.Pow(x, n); v < lim { 1699 | return v 1700 | } else { 1701 | fmt.Printf("%g >= %g\n", v, lim) 1702 | } 1703 | // 这里开始就不能使用 v 了 1704 | return lim 1705 | } 1706 | 1707 | func main() { 1708 | // 两个 pow 调用都在 main 调用 fmt.Println 前执行完毕了。 1709 | fmt.Println( 1710 | pow(3, 2, 10), 1711 | pow(3, 3, 20), 1712 | ) 1713 | } 1714 | ``` 1715 | 1716 | 在 if 的便捷语句定义的变量同样可以在任何对应的 else 块中使用。 1717 | 1718 | ### switch 语句 1719 | 1720 | ```go 1721 | package main 1722 | import ( 1723 | "fmt" 1724 | "runtime" 1725 | ) 1726 | func main() { 1727 | fmt.Print("Go runs on ") 1728 | switch os := runtime.GOOS; os { 1729 | case "darwin": 1730 | fmt.Println("OS X.") 1731 | case "linux": 1732 | fmt.Println("Linux.") 1733 | default: 1734 | // freebsd, openbsd, 1735 | // plan9, windows... 1736 | fmt.Printf("%s.", os) 1737 | } 1738 | } 1739 | ``` 1740 | 1741 | 在 if 的便捷语句定义的变量同样可以在任何对应的 else 块中使用。 1742 | 1743 | **switch 的执行顺序:** 条件从上到下的执行,当匹配成功的时候停止。 1744 | 1745 | ```go 1746 | package main 1747 | import ( 1748 | "fmt" 1749 | "time" 1750 | ) 1751 | func main() { 1752 | fmt.Println("When's Saturday?") 1753 | today := time.Now().Weekday() 1754 | switch time.Saturday { 1755 | case today + 0: 1756 | fmt.Println("Today.") 1757 | case today + 1: 1758 | fmt.Println("Tomorrow.") 1759 | case today + 2: 1760 | fmt.Println("In two days.") 1761 | default: 1762 | fmt.Println("Too far away.") 1763 | } 1764 | } 1765 | ``` 1766 | 1767 | **没有条件的 switch 同 switch true 一样。** 1768 | 1769 | ```go 1770 | package main 1771 | import ( 1772 | "fmt" 1773 | "time" 1774 | ) 1775 | func main() { 1776 | t := time.Now() 1777 | switch { 1778 | case t.Hour() < 12: 1779 | fmt.Println("Good morning!") 1780 | case t.Hour() < 17: 1781 | fmt.Println("Good afternoon.") 1782 | default: 1783 | fmt.Println("Good evening.") 1784 | } 1785 | } 1786 | ``` 1787 | 1788 | ### defer 语句 1789 | 1790 | ```go 1791 | package main 1792 | import "fmt" 1793 | func main() { 1794 | // 2. 在输出 world 1795 | defer fmt.Println("world") 1796 | // 1. 先输出 hello 1797 | fmt.Println("hello") 1798 | } 1799 | ``` 1800 | 1801 | > defer 语句会延迟函数的执行直到上层函数返回。 1802 | > 延迟调用的参数会立刻生成,但是在上层函数返回前函数都不会被调用。 1803 | 1804 | **defer 栈** 1805 | 1806 | 延迟的函数调用被压入一个栈中。当函数返回时, 会按照后进先出的顺序调用被延迟的函数调用。 1807 | 1808 | ```go 1809 | package main 1810 | import "fmt" 1811 | func main() { 1812 | fmt.Println("counting") 1813 | for i := 0; i < 10; i++ { 1814 | defer fmt.Println(i) 1815 | } 1816 | fmt.Println("done") 1817 | } 1818 | ``` 1819 | 1820 | 可以运行demo [defer](example/defer/defer.go) 查看效果。 1821 | 1822 | 1823 | 1824 | ## 结构体 1825 | 1826 | ### 结构体字段 1827 | 1828 | 结构体字段使用点号来访问。 1829 | 1830 | ```go 1831 | package main 1832 | import "fmt" 1833 | type Vertex struct { 1834 | X int 1835 | Y int 1836 | } 1837 | func main() { 1838 | v := Vertex{1, 2} 1839 | v.X = 4 1840 | fmt.Println(v.X) 1841 | } 1842 | ``` 1843 | 1844 | ### 结构体指针 1845 | 1846 | 结构体指针使用 & 来访问。 1847 | 1848 | ```go 1849 | package main 1850 | import "fmt" 1851 | type Vertex struct { 1852 | X int 1853 | Y int 1854 | } 1855 | func main() { 1856 | v := Vertex{1, 2} 1857 | p := &v 1858 | p.X = 1e9 1859 | fmt.Println(v) 1860 | } 1861 | 1862 | ``` 1863 | 1864 | ### 结构体文法 1865 | 1866 | > 结构体文法表示通过结构体字段的值作为列表来新分配一个结构体。 1867 | > 使用 Name: 语法可以仅列出部分字段。(字段名的顺序无关。) 1868 | > 特殊的前缀 & 返回一个指向结构体的指针。 1869 | 1870 | ```go 1871 | package main 1872 | import "fmt" 1873 | type Vertex struct { 1874 | X int 1875 | Y int 1876 | } 1877 | func main() { 1878 | v := Vertex{1, 2} 1879 | p := &v 1880 | p.X = 1e9 1881 | fmt.Println(v) 1882 | } 1883 | ``` 1884 | 1885 | 1886 | 1887 | ## 资源导航 1888 | 1889 |
1890 | 官方 1891 | 1892 | - [Playground](http://play.golang.org):Go 语言代码在线运行 1893 | 1894 |
1895 | 1896 |
1897 | 国内镜像 1898 | 1899 | - [Go 指南国内镜像](http://tour.golangtc.com/) 1900 | - [Go 语言国内下载镜像](http://www.golangtc.com/download) 1901 | - [Go 官方网站国内镜像](http://docs.studygolang.com/) 1902 | 1903 |
1904 | 1905 |
1906 | Web 框架 1907 | 1908 | - [mux](https://github.com/gorilla/mux): 一个强大的URL路由器和golang调度程序。 1909 | - [Iris](https://github.com/kataras/iris): 一个快速,简单但功能齐全且非常高效的Web框架。 1910 | - [gin](https://github.com/gin-gonic/gin): HTTP Web框架,它具有类似Martini的API,具有更好的性能 1911 | - [Macaron](https://go-macaron.com/): 模块化 Web 框架 1912 | - [Beego](http://beego.me/): 重量级 Web 框架 1913 | - [Revel](https://github.com/revel/revel): 较早成熟的重量级 Web 框架 1914 | - [Martini](https://github.com/go-martini/martini): 一个强大为了编写模块化 Web 应用而生的 Go 语言框架 1915 | - [web](https://github.com/hoisie/web): 轻量级超简单的 web 框架。 1916 | 1917 |
1918 | 1919 |
1920 | ORM 以及数据库驱动 1921 | 1922 | - [gorm](https://github.com/jinzhu/gorm): 支持 MySQL、PostgreSQL、SQLite3 以及 SQL Server 1923 | - [xorm](https://github.com/go-xorm/xorm): 支持 MySQL、PostgreSQL、SQLite3 以及 MsSQL 1924 | - [mgo](http://labix.org/mgo): MongoDB 官方推荐驱动 1925 | 1926 |
1927 | 1928 |
1929 | 辅助站点 1930 | 1931 | - [Go Walker](https://gowalker.org): Go 语言在线 API 文档 1932 | - [gobuild.io](http://gobuild.io/): Go 语言在线二进制编译与下载 1933 | - [Rego](http://regoio.herokuapp.com/): Go 语言正则在线测试 1934 | - [gopm.io](https://gopm.io): 科学下载第三方包 1935 | 1936 |
1937 | 1938 |
1939 | 其它文章 1940 | 1941 | > 文章资源来源与Go社区的[每日新闻](https://gocn.io/topic/%E6%AF%8F%E6%97%A5%E6%96%B0%E9%97%BB) 1942 | 1943 | - [使用Go和TensorFlow构建图片识别API](https://outcrawl.com/image-recognition-api-go-tensorflow/) 1944 | - [Golang C++11 中的原子操作对比](http://pp-qq.github.io/2017/10/18/go-c-atomic/) 1945 | - [Docker 镜像优化与最佳实践](http://weibo.com/ttarticle/p/show?id=2309614164586369582704&u=1889019865&m=4164582908028008&cu=2278216581) 1946 | - [微服务7篇介绍](https://www.nginx.com/blog/introduction-to-microservices/) 1947 | - [gogland eap 16 发布](https://blog.jetbrains.com/go/2017/10/18/gogland-eap-16-file-watcher-tons-of-new-inspections-smarter-navigate-to-test-and-more/) 1948 | - [在Google Go team工作体验](https://medium.com/@ljrudberg/working-on-the-go-team-at-google-917b2c8d35ff) 1949 | - [Go学习一月总结](https://blog.learngoprogramming.com/learn-go-programming-monthly-recap-a0b1e494393c) 1950 | - [devops的肮脏的秘密](https://chrisdodds.net/dirty-secrets-of-devops/) 1951 | - [从ELK到EFK](https://mp.weixin.qq.com/s/UMzq0Mt2_nm5pWn1Spba3Q) 1952 | - [我们怎么从Python切换到Go](https://getstream.io/blog/switched-python-go/) 1953 | - [Golang 微服务在腾讯游戏用户运营领域的探索及实践](http://www.infoq.com/cn/presentations/exploration-practice-of-golang-micro-service-in-the-tencent-game-users) 1954 | - [如何重构C++项目到Go](https://medium.com/@brendanleglaunec/how-refactoring-my-c-application-into-a-go-library-made-it-better-in-every-way-b99aa15fcfdf) 1955 | - [Go并发详解](https://gist.github.com/rushilgupta/228dfdf379121cb9426d5e90d34c5b96) 1956 | - [Go框架、IDE和工具集介绍](https://dzone.com/articles/golang-guide-a-list-of-top-golang-frameworks-ides) 1957 | - [Go开发大型分布式系统的好与坏](https://www.youtube.com/watch?v=8IKxf98h65Y) 1958 | - [RESTFul风格的API管理后台,基于beego和layui](https://github.com/george518/PPGo_ApiAdmin) 1959 | - [阿里云基于 Go 的微服务架构分享](https://mp.weixin.qq.com/s/Ftd8pFVCrhtppvFjBNSF5Q) 1960 | - [ElasticSearch 集群监控](http://www.54tianzhisheng.cn/2017/10/15/ElasticSearch-cluster-health-metrics/) 1961 | - [组织Go代码在一个大型repo经验之谈](https://blog.digitalocean.com/cthulhu-organizing-go-code-in-a-scalable-repo/) 1962 | - [基于openapi文档的自动化生产代码工具](https://github.com/jbowes/oag) 1963 | - [黑一下Go (实际上是作者不理解Go的interfaceO(∩_∩)O)](https://zhuanlan.zhihu.com/p/30120861) 1964 | - [基于nats的Go分布式微服务系统](https://medium.com/@shijuvar/building-distributed-systems-and-microservices-in-go-with-nats-streaming-d8b4baa633a2) 1965 | - [深入浅出 Raft - 基本概念](http://www.jianshu.com/p/138b4d267084) 1966 | - [RESTful API 设计最佳实践](http://www.zcfy.cc/article/restful-api-design-best-practices-in-a-nutshell-4388.html) 1967 | - [七个JWT最佳实践](https://dev.to/neilmadden/7-best-practices-for-json-web-tokens) 1968 | - [Go语言三驾马车](https://cloud.tencent.com/community/article/649192) 1969 | - [反射的原理与使用详解](http://www.cnblogs.com/susufufu/p/7653579.html) 1970 | - [从零构建一个神经网络](http://www.datadan.io/building-a-neural-net-from-scratch-in-go/) 1971 | - [glot图标库应用入门](https://medium.com/@Arafat./introducing-glot-the-plotting-library-for-golang-3133399948a1) 1972 | - [Go如何不适用CGO调用rust](https://speakerdeck.com/filosottile/calling-rust-from-go-without-cgo-at-gothamgo-2017) 1973 | - [GopherJS 令人惊讶的性能改进](https://medium.com/gopherjs/surprises-in-gopherjs-performance-4a0a49b04ecd) 1974 | - [Go 1.10 版本将支持编译window dll](https://go-review.googlesource.com/c/go/+/69091) 1975 | - [如何学习Go](https://dev.to/codehakase/how-i-learned-go-programming) 1976 | - [微服务组织](https://developers.redhat.com/blog/2017/08/02/organizing-microservices-modern-integration/) 1977 | - [玩转 Go Hack 之官方攻略 | 赛前指南](https://mp.weixin.qq.com/s/7mrxUxuQlOxDKxB2HTZHIw) 1978 | - [golang 标准库间依赖的可视化展示](http://blog.csdn.net/sinat_30800357/article/details/78178844) 1979 | - [golang——glide的使用手册](http://blog.csdn.net/lastsweetop/article/details/78185713) 1980 | - [hack CCTV视频库](https://github.com/EtixLabs/cameradar) 1981 | - [如何使用gRPC开发CS系统](https://medium.com/pantomath/how-we-use-grpc-to-build-a-client-server-system-in-go-dd20045fa1c2) 1982 | - [Go内存调优](https://blog.fmpwizard.com/2017/09/29/memory-profiling-in-go/) 1983 | - [Go奇葩点](https://i6448038.github.io/2017/10/06/GolangDetailsTwo/) 1984 | - [gRPC和RESTFul API性能对比](https://dev.to/plutov/benchmarking-grpc-and-rest-in-go-565) 1985 | - [graphql的概述](https://dzone.com/refcardz/an-overview-of-graphql) 1986 | - [2017年学习Go的视频和书籍集合](https://reactdom.com/blog/go-books) 1987 | - [《微服务:从设计到部署》](https://github.com/oopsguy/microservices-from-design-to-deployment-chinese) 1988 | - [基于openfaas的serverless服务](https://blog.alexellis.io/serverless-golang-with-openfaas/) 1989 | - [使用Go加密整个互联网](https://speakerdeck.com/filosottile/encrypting-the-internet-with-go-at-gophercon-2017) 1990 | - [go run -race的底层实现](https://speakerdeck.com/kavya719/go-run-race-under-the-hood) 1991 | - [监控和追踪Go服务](https://speakerdeck.com/chimeracoder/monitoring-and-tracing-your-go-services-gothamgo-2017) 1992 | - [如何优化高负载服务](https://blogs.dropbox.com/tech/2017/09/optimizing-web-servers-for-high-throughput-and-low-latency/) 1993 | - [Go概述](https://blog.learngoprogramming.com/about-go-language-an-overview-f0bee143597c) 1994 | - [Go之美](https://hackernoon.com/the-beauty-of-go-98057e3f0a7d) 1995 | - [k8s很酷的原因](https://jvns.ca/blog/2017/10/05/reasons-kubernetes-is-cool/) 1996 | - [Go实现的FaaS](https://github.com/fnproject/fn) 1997 | - [快速开发基于pg的API原型工具](https://github.com/dhax/go-base) 1998 | - [使用Go+gRPC打造高性能API](http://www.agiratech.com/building-high-performance-apis-go-grpc/) 1999 | - [log重负载应用的内存优化](http://agniva.me/go/2017/10/03/improving-log-write.html) 2000 | - [每个Gopher都应该值得关注的Go interface](https://www.writeingo.com/blog/important-go-interfaces/) 2001 | - [可视化调试Go程序](https://honeycomb.io/blog/2017/08/golang-observability-using-the-new-pprof-web-ui-to-debug-memory-usage/) 2002 | - [老程序员的感慨](https://mp.weixin.qq.com/s/G4KdOwoKNyTYOW3J3Wk7qA) 2003 | - [如何使用gonum进行数据统计](https://sbinet.github.io/posts/2017-10-04-intro-to-stats-with-gonum/) 2004 | - [深入理解channel笔记](https://blog.lab99.org/post/golang-2017-10-04-video-understanding-channels.html) 2005 | - [使用Go写出优雅的代码](https://scene-si.org/2017/10/04/elegant-code-and-go/) 2006 | - [Java开发者的Go指南](https://dzone.com/articles/making-the-jump-to-go-a-guide-for-java-developers) 2007 | - [Go 1.8.4 和Go 1.9.1 发布](https://groups.google.com/forum/m/#!topic/golang-nuts/sHfMg4gZNps) 2008 | - [Google开源的Go实现的配置语言](https://github.com/google/skylark) 2009 | - [老王出品的k8s完整教程](https://github.com/jolestar/kubernetes-complete-course) 2010 | - [Go实现的lua VM](https://github.com/milochristiansen/lua) 2011 | - [基于kafka和Go的微服务实现和测试](https://semaphoreci.com/community/tutorials/writing-and-testing-an-event-sourcing-microservice-with-kafka-and-go) 2012 | - [swift调用Go实例](https://medium.com/@rakyll/calling-go-from-swift-be88709942c3) 2013 | - [Go for rails](https://sphereinc.com/go-for-rails-developers/) 2014 | - [fmt包详解](https://medium.com/go-walkthrough/go-walkthrough-fmt-55a14bbbfc53) 2015 | - [基于 Linux bcc/BPF 实现 Go 程序动态追踪](http://www.jianshu.com/p/f1781fc452f6) 2016 | - [如何测试Go程序](https://getstream.io/blog/how-we-test-go-at-stream/) 2017 | - [Go如何改善性能](https://www.youtube.com/watch?v=DJ4d_PZ6Gns) 2018 | 2019 |
2020 | 2021 | 2022 | ## Contributors 2023 | 2024 | As always, thanks to our amazing contributors! 2025 | 2026 | 2027 | 2028 | 2029 | 2030 | Made with [action-contributors](https://github.com/jaywcjlove/github-action-contributors). 2031 | 2032 | ## License 2033 | 2034 | Licensed under the MIT License. 2035 | 2036 | -------------------------------------------------------------------------------- /example/array/array.go: -------------------------------------------------------------------------------- 1 | package main 2 | import "fmt" 3 | func main() { 4 | // 声明一个长度为5的整数数组 5 | // 一旦数组被声明了,那么它的数据类型跟长度都不能再被改变。 6 | var array1 [5]int 7 | 8 | fmt.Printf("array1: %d\n\n", array1) 9 | 10 | // 声明一个长度为5的整数数组 11 | // 初始化每个元素 12 | array2 := [5]int{12, 123, 1234, 12345, 123456} 13 | array2[1] = 5000 14 | fmt.Printf("array2: %d\n\n", array2[1]) 15 | 16 | // n 是一个长度为 10 的数组 17 | var n [10]int 18 | var i,j int 19 | 20 | /* 为数组 n 初始化元素 */ 21 | for i = 0; i < 10; i++ { 22 | n[i] = i + 100 /* 设置元素为 i + 100 */ 23 | } 24 | 25 | /* 输出每个数组元素的值 */ 26 | for j = 0; j < 10; j++ { 27 | fmt.Printf("Element[%d] = %d\n", j, n[j] ) 28 | } 29 | 30 | /* 数组 - 5 行 2 列*/ 31 | var a = [5][2]int{ {0,0}, {1,2}, {2,4}, {3,6},{4,8}} 32 | var e, f int 33 | 34 | /* 输出数组元素 */ 35 | for e = 0; e < 5; e++ { 36 | for f = 0; f < 2; f++ { 37 | fmt.Printf("a[%d][%d] = %d\n", e,f, a[e][f] ) 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /example/byte/byte.go: -------------------------------------------------------------------------------- 1 | package main 2 | import ( 3 | "bytes" 4 | "fmt" 5 | ) 6 | func main() { 7 | // 这里不能写成 b := []byte{"Golang"},这里是利用类型转换。 8 | b := []byte("Golang") 9 | subslice1 := []byte("go") 10 | subslice2 := []byte("Go") 11 | // func Contains(b, subslice [] byte) bool 12 | // 检查字节切片b ,是否包含子字节切片 subslice 13 | fmt.Println(bytes.Contains(b, subslice1)) 14 | fmt.Println(bytes.Contains(b, subslice2)) 15 | 16 | 17 | s2 := []byte("同学们,上午好") 18 | m := func(r rune) rune { 19 | if r == '上' { 20 | r = '下' 21 | } 22 | return r 23 | } 24 | fmt.Println(string(s2)) 25 | // func Map(mapping func(r rune) rune, s []byte) []byte 26 | // Map函数: 首先将 s 转化为 UTF-8编码的字符序列, 27 | // 然后使用 mapping 将每个Unicode字符映射为对应的字符, 28 | // 最后将结果保存在一个新的字节切片中。 29 | fmt.Println(string(bytes.Map(m, s2))) 30 | 31 | 32 | s3 := []byte("google") 33 | old := []byte("o") 34 | //这里 new 是一个字节切片,不是关键字了 35 | new := []byte("oo") 36 | n := 1 37 | // func Replace(s, old, new []byte, n int) []byte 38 | //返回字节切片 S 的一个副本, 并且将前n个不重叠的子切片 old 替换为 new,如果n < 0 那么不限制替换的数量 39 | fmt.Println(string(bytes.Replace(s3, old, new, n))) 40 | fmt.Println(string(bytes.Replace(s3, old, new, -1))) 41 | 42 | 43 | // 将字节切片 转化为对应的 UTF-8编码的字节序列,并且返回对应的 Unicode 切片。 44 | s4 := []byte("中华人民共和国") 45 | r1 := bytes.Runes(s4) 46 | // func Runes(b []byte) []rune 47 | fmt.Println(string(s4), len(s4)) // 字节切片的长度 48 | fmt.Println(string(r1), len(r1)) // rune 切片的长度 49 | 50 | 51 | // 字节切片 的每个元素,依旧是字节切片。 52 | s5 := [][]byte{ 53 | []byte("你好"), 54 | []byte("世界"), //这里的逗号,必不可少 55 | } 56 | sep := []byte(",") 57 | // func Join(s [][]byte, sep []byte) []byte 58 | // 用字节切片 sep 吧 s中的每个字节切片连接成一个,并且返回. 59 | fmt.Println(string(bytes.Join(s5, sep))) 60 | } -------------------------------------------------------------------------------- /example/const/const.go: -------------------------------------------------------------------------------- 1 | package main 2 | import "unsafe" 3 | 4 | // 常量可以用len(), cap(), unsafe.Sizeof()常量计算表达式的值。 5 | // 常量表达式中,函数必须是内置函数,否则编译不过: 6 | const ( 7 | a = "abc" 8 | b = len(a) 9 | c = unsafe.Sizeof(a) 10 | ) 11 | 12 | func main(){ 13 | const ( 14 | PI = 3.14 15 | const1 = "1" 16 | ) 17 | const LENGTH int = 10 18 | const e, f, g = 1, false, "str" //多重赋值 19 | println(a, b, c,PI, LENGTH) 20 | } -------------------------------------------------------------------------------- /example/defer/defer.go: -------------------------------------------------------------------------------- 1 | package main 2 | import "fmt" 3 | func main() { 4 | // 2. 在输出 world 5 | defer fmt.Println("world") 6 | // 1. 先输出 hello 7 | fmt.Println("hello") 8 | // 输出结果 9 | // ======= 10 | // hello 11 | // world 12 | 13 | 14 | fmt.Println("counting") 15 | for i := 0; i < 10; i++ { 16 | defer fmt.Println(i) 17 | } 18 | fmt.Println("done") 19 | // 输出结果 20 | // ======= 21 | // counting 22 | // done 23 | // 9 24 | // 8 25 | // 7 26 | // 6 27 | // 5 28 | // 4 29 | // 3 30 | // 2 31 | // 1 32 | // 0 33 | } -------------------------------------------------------------------------------- /example/float/float.go: -------------------------------------------------------------------------------- 1 | package main 2 | import "fmt" 3 | 4 | func main() { 5 | var x float64 6 | x = 20.0 7 | fmt.Println(x) 8 | fmt.Printf("x is of type %T\n", x) 9 | 10 | a := float64(20.0) 11 | b := 42 12 | fmt.Println(a) 13 | fmt.Println(b) 14 | fmt.Printf("a is of type %T\n", a) 15 | fmt.Printf("b is of type %T\n", b) 16 | } -------------------------------------------------------------------------------- /example/func/func.go: -------------------------------------------------------------------------------- 1 | package main 2 | import "fmt" 3 | 4 | type functinTyoe func(int, int)// // 声明了一个函数类型 5 | 6 | func (f functinTyoe)Serve() { 7 | fmt.Println("serve2") 8 | } 9 | 10 | func serve(int,int) { 11 | fmt.Println("serve1") 12 | } 13 | 14 | func main() { 15 | a := functinTyoe(serve) 16 | a(1,2) 17 | a.Serve() 18 | } -------------------------------------------------------------------------------- /example/hello/hello.go: -------------------------------------------------------------------------------- 1 | package main //1 2 | 3 | import "fmt" //2 4 | 5 | func main() {//3 6 | fmt.Println("Hello, World!")//4 7 | } 8 | -------------------------------------------------------------------------------- /example/inteface/inteface.go: -------------------------------------------------------------------------------- 1 | package main 2 | import ( 3 | "fmt" 4 | "math" 5 | ) 6 | 7 | /* 定义一个 interface */ 8 | type shape interface { 9 | area() float64 10 | } 11 | 12 | /* 定义一个 circle */ 13 | type circle struct { 14 | x,y,radius float64 15 | } 16 | 17 | /* 定义一个 rectangle */ 18 | type rectangle struct { 19 | width, height float64 20 | } 21 | 22 | /* 定义一个circle方法 (实现 shape.area())*/ 23 | func(circle circle) area() float64 { 24 | return math.Pi * circle.radius * circle.radius 25 | } 26 | 27 | /* 定义一个rectangle方法 (实现 shape.area())*/ 28 | func(rect rectangle) area() float64 { 29 | return rect.width * rect.height 30 | } 31 | 32 | /* 定义一个shape的方法*/ 33 | func getArea(shape shape) float64 { 34 | return shape.area() 35 | } 36 | 37 | func main() { 38 | circle := circle{x:0,y:0,radius:5} 39 | rectangle := rectangle {width:10, height:5} 40 | 41 | fmt.Printf("circle area: %f\n",getArea(circle)) 42 | fmt.Printf("rectangle area: %f\n",getArea(rectangle)) 43 | } 44 | -------------------------------------------------------------------------------- /example/iota/iota.go: -------------------------------------------------------------------------------- 1 | package main 2 | import "fmt" 3 | func main() { 4 | const ( 5 | // 第一个 iota 等于 0,每当 iota 在新的一行被使用时,它的值都会自动加 1; 6 | // 所以 a=0, b=1, c=2 可以简写为如下形式: 7 | a = iota //0 8 | b //1 9 | c //2 10 | d = "ha" //独立值,iota += 1 11 | e //"ha" iota += 1 12 | f = 100 //iota +=1 13 | g //100 iota +=1 14 | h = iota //7,恢复计数 15 | i //8 16 | ) 17 | fmt.Println(a,b,c,d,e,f,g,h,i) 18 | } -------------------------------------------------------------------------------- /example/module/README.md: -------------------------------------------------------------------------------- 1 | 2 | ## 初始化工程 3 | 4 | ```bash 5 | mkdir mod2 6 | cd mod2 7 | go mod init mod2 8 | ``` 9 | 10 | ## 安装包 11 | 12 | ```bash 13 | go get -m github.com/gin-gonic/gin@v1.3.0 14 | 15 | go get github.com/gorilla/mux # 匹配最新的一个 tag 16 | go get github.com/gorilla/mux@latest # 和上面一样 17 | go get github.com/gorilla/mux@v1.6.2 # 匹配 v1.6.2 18 | go get github.com/gorilla/mux@e3702bed2 # 匹配 v1.6.2 19 | go get github.com/gorilla/mux@c856192 # 匹配 c85619274f5d 20 | go get github.com/gorilla/mux@master # 匹配 master 分支 21 | ``` 22 | 23 | 1. 通过 `go get` 切换版本 24 | 2. 执行 `go mod vendor` 将依赖复制到vendor下 25 | 3. 通过 `go mod tidy` 命令可以移除 `go.mod` 中不再使用的依赖 26 | 27 | ## 设置代理 28 | 29 | ```bash 30 | # bash mac 31 | export GOPROXY=https://goproxy.io 32 | ``` 33 | 34 | ## mod 命令 35 | 36 | ```bash 37 | go help mod 38 | # Go mod provides access to operations on modules. 39 | 40 | # Note that support for modules is built into all the go commands, 41 | # not just 'go mod'. For example, day-to-day adding, removing, upgrading, 42 | # and downgrading of dependencies should be done using 'go get'. 43 | # See 'go help modules' for an overview of module functionality. 44 | 45 | Usage: 46 | 47 | go mod [arguments] 48 | 49 | The commands are: 50 | 51 | download download modules to local cache 52 | edit edit go.mod from tools or scripts 53 | graph print module requirement graph 54 | init initialize new module in current directory 55 | tidy add missing and remove unused modules 56 | vendor make vendored copy of dependencies 57 | verify verify dependencies have expected content 58 | why explain why packages or modules are needed 59 | 60 | Use "go help mod " for more information about a command. 61 | ``` 62 | 63 | - `download`: download modules to local cache (下载依赖的module到本地cache) 64 | - `edit`: edit go.mod from tools or scripts (编辑go.mod文件) 65 | - `graph`: print module requirement graph (打印模块依赖图) 66 | - `init`: initialize new module in current directory (再当前文件夹下初始化一个新的module, 创建go.mod文件) 67 | - `tidy`: add missing and remove unused modules (增加丢失的module,去掉未用的module) 68 | - `vendor`: make vendored copy of dependencies (将依赖复制到vendor下) 69 | - `verify`: verify dependencies have expected content (校验依赖) 70 | - `why`: explain why packages or modules are needed (解释为什么需要依赖) -------------------------------------------------------------------------------- /example/module/go.mod: -------------------------------------------------------------------------------- 1 | module mod2 2 | 3 | go 1.17 4 | 5 | require ( 6 | github.com/gin-contrib/sse v0.1.0 // indirect 7 | github.com/gin-gonic/gin v1.8.1 8 | github.com/golang/protobuf v1.5.0 // indirect 9 | github.com/json-iterator/go v1.1.12 // indirect 10 | github.com/mattn/go-isatty v0.0.14 // indirect 11 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 12 | github.com/modern-go/reflect2 v1.0.2 // indirect 13 | github.com/stretchr/testify v1.7.1 // indirect 14 | github.com/ugorji/go/codec v1.2.7 // indirect 15 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 // indirect 16 | golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 // indirect 17 | golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069 // indirect 18 | gopkg.in/go-playground/assert.v1 v1.2.1 // indirect 19 | gopkg.in/go-playground/validator.v8 v8.18.2 // indirect 20 | gopkg.in/yaml.v2 v2.4.0 // indirect 21 | ) 22 | 23 | require ( 24 | github.com/davecgh/go-spew v1.1.1 // indirect 25 | github.com/go-playground/assert/v2 v2.0.1 // indirect 26 | github.com/go-playground/locales v0.14.0 // indirect 27 | github.com/go-playground/universal-translator v0.18.0 // indirect 28 | github.com/go-playground/validator/v10 v10.10.0 // indirect 29 | github.com/goccy/go-json v0.9.7 // indirect 30 | github.com/google/gofuzz v1.0.0 // indirect 31 | github.com/leodido/go-urn v1.2.1 // indirect 32 | github.com/pelletier/go-toml/v2 v2.0.1 // indirect 33 | github.com/pmezard/go-difflib v1.0.0 // indirect 34 | github.com/stretchr/objx v0.1.0 // indirect 35 | github.com/ugorji/go v1.2.7 // indirect 36 | golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirect 37 | golang.org/x/text v0.3.6 // indirect 38 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e // indirect 39 | google.golang.org/protobuf v1.28.0 // indirect 40 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect 41 | ) 42 | -------------------------------------------------------------------------------- /example/module/go.sum: -------------------------------------------------------------------------------- 1 | github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 2 | github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= 3 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 4 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 5 | github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7 h1:AzN37oI0cOS+cougNAV9szl6CVoj2RYwzS3DpUQNtlY= 6 | github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= 7 | github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= 8 | github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= 9 | github.com/gin-gonic/gin v1.3.0 h1:kCmZyPklC0gVdL728E6Aj20uYBJV93nj/TkwBTKhFbs= 10 | github.com/gin-gonic/gin v1.3.0/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6mUr7Y= 11 | github.com/gin-gonic/gin v1.7.4 h1:QmUZXrvJ9qZ3GfWvQ+2wnW/1ePrTEJqPKMYEU3lD/DM= 12 | github.com/gin-gonic/gin v1.7.4/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= 13 | github.com/gin-gonic/gin v1.7.7 h1:3DoBmSbJbZAWqXJC3SLjAPfutPJJRN1U5pALB7EeTTs= 14 | github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U= 15 | github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8= 16 | github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk= 17 | github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= 18 | github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= 19 | github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= 20 | github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= 21 | github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= 22 | github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= 23 | github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= 24 | github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= 25 | github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= 26 | github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= 27 | github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= 28 | github.com/go-playground/validator/v10 v10.10.0 h1:I7mrTYv78z8k8VXa/qJlOlEXn/nBh+BF8dHX5nt/dr0= 29 | github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= 30 | github.com/goccy/go-json v0.9.7 h1:IcB+Aqpx/iMHu5Yooh7jEzJk1JZ7Pjtmys2ukPr7EeM= 31 | github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= 32 | github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= 33 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 34 | github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I= 35 | github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= 36 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 37 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 38 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 39 | github.com/json-iterator/go v1.1.5 h1:gL2yXlmiIo4+t+y32d4WGwOjKGYcGOuyrg46vadswDE= 40 | github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= 41 | github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= 42 | github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= 43 | github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= 44 | github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= 45 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 46 | github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= 47 | github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= 48 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 49 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 50 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 51 | github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= 52 | github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= 53 | github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= 54 | github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= 55 | github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs= 56 | github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= 57 | github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= 58 | github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= 59 | github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= 60 | github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= 61 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 62 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= 63 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 64 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 65 | github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= 66 | github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 67 | github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= 68 | github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= 69 | github.com/pelletier/go-toml/v2 v2.0.1 h1:8e3L2cCQzLFi2CR4g7vGFuFxX7Jl1kKX8gW+iV0GUKU= 70 | github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= 71 | github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= 72 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 73 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 74 | github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= 75 | github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= 76 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 77 | github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= 78 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 79 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 80 | github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 81 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 82 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 83 | github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= 84 | github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= 85 | github.com/ugorji/go v1.2.7 h1:qYhyWUUd6WbiM+C6JZAUkIJt/1WrjzNHY9+KCIjVqTo= 86 | github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= 87 | github.com/ugorji/go/codec v0.0.0-20181209151446-772ced7fd4c2 h1:EICbibRW4JNKMcY+LsWmuwob+CRS1BmdRdjphAm9mH4= 88 | github.com/ugorji/go/codec v0.0.0-20181209151446-772ced7fd4c2/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= 89 | github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= 90 | github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= 91 | github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= 92 | github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= 93 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 94 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= 95 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 96 | golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI= 97 | golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 98 | golang.org/x/net v0.0.0-20190110200230-915654e7eabc h1:Yx9JGxI1SBhVLFjpAkWMaO1TF+xyqtHLjZpvQboJGiM= 99 | golang.org/x/net v0.0.0-20190110200230-915654e7eabc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 100 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 101 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw= 102 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 103 | golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw= 104 | golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 105 | golang.org/x/sys v0.0.0-20190116161447-11f53e031339 h1:g/Jesu8+QLnA0CPzF3E1pURg0Byr7i6jLoX5sqjcAh0= 106 | golang.org/x/sys v0.0.0-20190116161447-11f53e031339/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 107 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 108 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 109 | golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg= 110 | golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 111 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 112 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 113 | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 114 | golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069 h1:siQdpVirKtzPhKl3lZWozZraCFObP8S1v6PRp0bLrtU= 115 | golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 116 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 117 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 118 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 119 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 120 | golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= 121 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 122 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 123 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 124 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 125 | google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= 126 | google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 127 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 128 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 129 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 130 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= 131 | gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= 132 | gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM= 133 | gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= 134 | gopkg.in/go-playground/validator.v8 v8.18.2 h1:lFB4DoMU6B626w8ny76MV7VX6W2VHct2GVOI3xgiMrQ= 135 | gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= 136 | gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= 137 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 138 | gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= 139 | gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 140 | gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= 141 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 142 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 143 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 144 | -------------------------------------------------------------------------------- /example/module/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | 4 | import ( 5 | "html/template" 6 | "log" 7 | "os" 8 | "github.com/gin-gonic/gin" 9 | ) 10 | 11 | var html = template.Must(template.New("https").Parse(` 12 | 13 | 14 | Https Test 15 | 16 | 17 |

Welcome, golang!

18 | 19 | 20 | `)) 21 | 22 | 23 | func main() { 24 | logger := log.New(os.Stderr, "", 0) 25 | logger.Println("[WARNING] DON'T USE THE EMBED CERTS FROM THIS EXAMPLE IN PRODUCTION ENVIRONMENT, GENERATE YOUR OWN!") 26 | 27 | r := gin.Default() 28 | r.SetHTMLTemplate(html) 29 | 30 | r.GET("/", func(c *gin.Context) { 31 | c.HTML(200, "https", gin.H{ 32 | "status": "success", 33 | }) 34 | }) 35 | 36 | // Listen and Server in https://127.0.0.1:8080 37 | r.Run(":8083") 38 | } -------------------------------------------------------------------------------- /example/package-demo/cal/add.go: -------------------------------------------------------------------------------- 1 | package cal 2 | 3 | func Add(num1 int,num2 int) (result int) { 4 | return num1 + num2 5 | } -------------------------------------------------------------------------------- /example/package-demo/cal/multi/multiply.go: -------------------------------------------------------------------------------- 1 | package multi 2 | 3 | func Multi(num1 int, num2 int) (result int) { 4 | return num1 * num2 5 | } -------------------------------------------------------------------------------- /example/package-demo/cal/subtract.go: -------------------------------------------------------------------------------- 1 | package cal 2 | 3 | func Subtract(num1 int,num2 int) (result int) { 4 | return num1 + num2 5 | } -------------------------------------------------------------------------------- /example/package-demo/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "package-demo/cal/multi" 6 | "package-demo/cal" 7 | ) 8 | 9 | func main() { 10 | 11 | result := multi.Multi(1,2) 12 | fmt.Printf("%d\n",result) 13 | 14 | result2 := cal.Add(1,2) 15 | fmt.Printf("%d\n",result2) 16 | 17 | result3 := cal.Subtract(1,2) 18 | fmt.Printf("%d\n",result3) 19 | 20 | } -------------------------------------------------------------------------------- /example/print/print1.go: -------------------------------------------------------------------------------- 1 | package main 2 | import "fmt" 3 | import "os" 4 | 5 | type point struct { 6 | x, y int 7 | } 8 | 9 | // Go by Example: String Formatting 10 | // https://gobyexample.com/string-formatting 11 | func main() { 12 | 13 | // 旗标、宽度、精度、索引 14 | fmt.Printf("\n旗标、宽度、精度、索引\n----\n") 15 | // fmt.Printf("|%0+- #[1]*.[2]*[3]d|%0+- #[1]*.[2]*[4]d|\n", 8, 4, 32, 64) 16 | fmt.Printf("|%v|\n", 8) 17 | 18 | // 格式化排版 19 | fmt.Printf("\n格式化排版\n----\n") 20 | fmt.Printf("|%6d|%9d|\n", 12, 345) 21 | fmt.Printf("|%6.2f|%9.2f|\n", 1.2, 3.45) 22 | fmt.Printf("|%-6.2f|%-9.2f|\n", 1.2, 3.450999) 23 | 24 | // 浮点型精度 25 | fmt.Printf("\n浮点型精度\n----\n") 26 | fmt.Printf("|%f|%8.4f|%8.f|%.4f|%.f|\n", 3.2, 3.2, 3.2, 3.2, 3.2) 27 | fmt.Printf("|%.3f|%.3g|\n", 12.345678, 12.345678) 28 | fmt.Printf("|%.2f|\n", 12.345678+12.345678i) 29 | 30 | // 字符串精度 31 | fmt.Printf("\n字符串精度\n----\n") 32 | s := "你好世界!" 33 | fmt.Printf("|%29s|%8.2s|%8.s|%.2s|%.s|\n", s, s, s, s, s) 34 | fmt.Printf("|%29x|%8.2x|%8.x|%.2x|%.x|\n", s, s, s, s, s) 35 | 36 | // 带引号字符串 37 | fmt.Printf("\n带引号字符串\n----\n") 38 | s1 := "Hello 世界!" // CanBackquote 39 | s2 := "Hello\n世界!" // !CanBackquote 40 | fmt.Printf("%q\n", s1) // 双引号 41 | fmt.Printf("%#q\n", s1) // 反引号成功 42 | fmt.Printf("%#q\n", s2) // 反引号失败 43 | fmt.Printf("%+q\n", s2) // 仅包含 ASCII 字符 44 | 45 | // Unicode 码点 46 | fmt.Printf("\nUnicode 码点\n----\n") 47 | fmt.Printf("%U, %#U\n", '好', '好') 48 | fmt.Printf("%U, %#U\n", '\n', '\n') 49 | 50 | // 接口类型将输出其内部包含的值 51 | fmt.Printf("\n接口类型将输出其内部包含的值\n----\n") 52 | var i interface{} = struct { 53 | name string 54 | age int 55 | }{"AAA", 20} 56 | fmt.Printf("%v\n", i) // 只输出字段值 57 | fmt.Printf("%+v\n", i) // 同时输出字段名 58 | fmt.Printf("%#v\n", i) // Go 语法格式 59 | 60 | // 结构类型将输出其内部包含的值 61 | fmt.Printf("\n结构类型将输出其内部包含的值\n----\n") 62 | p := point{1, 2} 63 | fmt.Printf("%v\n", p) 64 | fmt.Printf("%+v\n", p) 65 | fmt.Printf("%#v\n", p) 66 | 67 | // 输出类型 68 | fmt.Printf("\n输出类型\n----\n") 69 | fmt.Printf("%T\n", i) 70 | fmt.Fprintf(os.Stderr, "an %s\n", "errorss") 71 | } -------------------------------------------------------------------------------- /example/structs/structs_fields.go: -------------------------------------------------------------------------------- 1 | package main 2 | import "fmt" 3 | 4 | type struct1 struct { 5 | i1 int 6 | f1 float32 7 | str string 8 | } 9 | 10 | func main() { 11 | ms := new(struct1) 12 | ms.i1 = 10 13 | ms.f1 = 15.5 14 | ms.str= "Chris" 15 | 16 | fmt.Printf("The int is: %d\n", ms.i1) 17 | fmt.Printf("The float is: %f\n", ms.f1) 18 | fmt.Printf("The string is: %s\n", ms.str) 19 | fmt.Println(ms) 20 | } -------------------------------------------------------------------------------- /idoc.yml: -------------------------------------------------------------------------------- 1 | menus: 2 | 首页: index.html 3 | 官方文档: 4 | url: https://golang.org 5 | target: __blank 6 | 赞助: https://jaywcjlove.github.io/#/sponsor 7 | 8 | editButton: 9 | label: GitHub 上编辑此页 10 | url: https://github.com/jaywcjlove/golang-tutorial/blob/master/ 11 | 12 | footer: | 13 | Released under the MIT License. Copyright © 2022 Kenny Wong
14 | Generated by idoc v{{idocVersion}} -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.0", 3 | "title": "Go 语言快速入门", 4 | "scripts": { 5 | "start": "idoc --watch", 6 | "build": "idoc" 7 | }, 8 | "repository": { 9 | "type": "git", 10 | "url": "https://github.com/jaywcjlove/golang-tutorial" 11 | }, 12 | "devDependencies": { 13 | "idoc": "^1.21.4" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "config:base" 4 | ], 5 | "packageRules": [ 6 | { 7 | "matchPackagePatterns": ["*"], 8 | "rangeStrategy": "replace" 9 | } 10 | ] 11 | } 12 | --------------------------------------------------------------------------------