惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

P
Palo Alto Networks Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
C
CERT Recently Published Vulnerability Notes
C
Cybersecurity and Infrastructure Security Agency CISA
S
Schneier on Security
S
Securelist
酷 壳 – CoolShell
酷 壳 – CoolShell
C
CXSECURITY Database RSS Feed - CXSecurity.com
Cyberwarzone
Cyberwarzone
Apple Machine Learning Research
Apple Machine Learning Research
S
SegmentFault 最新的问题
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
GbyAI
GbyAI
Security Latest
Security Latest
Last Week in AI
Last Week in AI
Microsoft Security Blog
Microsoft Security Blog
云风的 BLOG
云风的 BLOG
Recorded Future
Recorded Future
Webroot Blog
Webroot Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
TaoSecurity Blog
TaoSecurity Blog
C
Cisco Blogs
博客园 - 【当耐特】
Blog — PlanetScale
Blog — PlanetScale
Hugging Face - Blog
Hugging Face - Blog
B
Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Attack and Defense Labs
Attack and Defense Labs
The Last Watchdog
The Last Watchdog
U
Unit 42
阮一峰的网络日志
阮一峰的网络日志
Project Zero
Project Zero
WordPress大学
WordPress大学
L
LINUX DO - 最新话题
F
Fortinet All Blogs
L
LINUX DO - 热门话题
PCI Perspectives
PCI Perspectives
Simon Willison's Weblog
Simon Willison's Weblog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
MongoDB | Blog
MongoDB | Blog
Latest news
Latest news
P
Proofpoint News Feed
T
Threat Research - Cisco Blogs
The Hacker News
The Hacker News
爱范儿
爱范儿
O
OpenAI News
J
Java Code Geeks
T
The Exploit Database - CXSecurity.com
H
Hackread – Cybersecurity News, Data Breaches, AI and More

ZDDHUB

PixelsMeasure 开发第二年总结 PixelsMeasure 开发一年总结 Swift/SwiftUI 踩坑记 为什么说 GPT 利好程序员 ChatGPT 编程实现 Web 数字水印 Web 数字水印探究 Micro Frontends for Mobile URL 加载系统(URL Loading System) Protocol Buffers GraphQL 从 0 到 1 开发一款 IOS 应用 - Swift MV* 软件设计架构 学习一个新技巧需要多久? 不停机数据库迁移 Rspec 如何 mock update 方法更新自己? Rails 使用 mysql2 出现的段错误 使用 Docker-compose 部署 Rails 应用到生产环境 Cocoa troubleshooting 独孤九剑 Dit (0x05) - 终端篇 Gem-based Jekyll theme 开发小记 Miscellaneous 前端手记 TodoMVC 之 Redux 篇 前端手记 TodoMVC 之 Server 篇 前端手记 TodoMVC 之 React 篇 前端手记 TodoMVC 之 CSS 篇 独孤九剑 Dit (0x04) - 测试篇 独孤九剑 Dit (0x03) - 缓存篇 英语小抄 LLDB debug Golang Make mistakes 大牛俱乐部上线啦 独孤九剑 Dit (0x02) - 数据结构篇 独孤九剑 Dit (0x01) - 总决 独孤九剑 Dit (0x00) - 我为什么要做 Dit 零值强制类型转换的使用 终端颜色输出重定向 Go语法简略 - 正则表达式 Makefile Go语法简略 - Duck框架探索 Go语法简略 - 依赖注入 Go语法简略 - web应用框架 Go语法简略 - 反射 Go语法简略 - 面向对象 Go语法简略 - goroutine Go语法简略 - 方法和接口 大牛 轻松科研 未来这几年 为 Android Studio 创建图标 Shell Git Vim 金庸答百问 论拖延症 Flex, A fast scanner generator 有理想的人 从虚拟到现实 常用视频转接口 Recognizer configuration on CentOS 整个世界清静了 《Python源码剖析》读书笔记
Go语法简略 - 基础篇
zddhub · 2015-06-22 · via ZDDHUB

优秀的程序员应该不限于只用一两种语言,对各种语言都要有猎涉,这样才能在合适的应用下选择最合适的语言。但优秀的程序员至少需要精通一到两种语言,在众多的编程语言中,我选择 Go 和 Swift 作为自己之后20年内的主要编程语言。

本文主要记录 Go 的基础语法,方便查询。

0. Hello world

package main

import "fmt"

func main() {
  fmt.Println("Hello, 世界") // 语句结尾没有分号,当然这个也可以有
}

Go程序是由包组成的,从main package的main函数开始运行。import导入包”fmt”,调用Println打印”Hello, 世界”。

1. 变量

package main

import "fmt"

var c, python, java bool // 变量由var声明,类型放在最后

var j, k int = 1, 2 // 赋初值

// error := "这种赋值语句不允许出现在函数之外"
// const Pi := 3.14 - 常量不能使用:=
const Pi = 3.14

func main() {
  var i int
  fmt.Println(i, c, python, java) // 变量会被默认赋初值
  //: 0 false false false (//: 表示运行结果)

  var c, python, java = true, false, "no!"
  fmt.Println(j, k, c, python, java)
  //: 1 2 true false no!

  x := 3 // 自动识别变量类型
  l, m, n := true, false, "no!"
  fmt.Println(x, l, m, n)
  //: 3 true false no!

  fmt.Println(Pi)
  //: 3.14
}

2. 选择

package main

import (
  "fmt"
  "math"
)

func sqrt(x float64) string {
  if x < 0 { // 和C类似,去掉了小括号
    return sqrt(-x) + "i"
  }
  return fmt.Sprint(math.Sqrt(x))
}

func pow(x, n, lim float64) float64 {
  if v := math.Pow(x, n); v < lim { // if语句内可使用:=赋值
    return v
  } else {
    fmt.Printf("%g >= %g\n", v, lim) // else 语句
    //: 27 >= 20
  }
  // fmt.Println(v) - 变量v的作用域仅在if语句之内
  return lim
}

func main() {
  fmt.Println(sqrt(2), sqrt(-4))
  //: 1.4142135623730951 2i
  fmt.Println(pow(3, 2, 10), pow(3, 3, 20))
  //: 9 20
}

3. 循环

Go只有一种循环结构,for循环。

package main

import "fmt"

func main() {
  sum := 0
  for i := 0; i < 10; i++ { // 与C类似,取消了小括号
    sum += i
  }
  fmt.Println(sum)
  //: 45

  sum = 1
  for ; sum < 1000; { // 可省略部分参数
    sum += sum
  }
  fmt.Println(sum)
  //: 1024

  sum = 1
  for sum < 1000 { // 实现类似while的功能
    sum += sum
  }
  fmt.Println(sum)
  //: 1024

  for { // 死循环
    fmt.Println("I loop forever, please use ctrl+c and exit.");
  }
}

4. 函数

package main

import "fmt"

func add(x, y int) int { // 函数用func申明
  return x + y
}

func swap(x, y string) (string, string) {
  return y, x // 可以有多个返回值
}

func split(sum int) (x, y int) {
  x = sum * 4 / 9
  y = sum - x
  return // 根据参数列表返回相应的值,可读性差,少使用
}

func main() {
  fmt.Println(add(15, 24))
  //: 39

  a, b := swap("hub", "zdd")
  fmt.Printf("%v%v\n", a, b)
  //: zddhub

  fmt.Println(split(17))
  //: 7 10
}

5. 基础数据类型

bool

string

int  int8  int16  int32  int64
uint uint8 uint16 uint32 uint64 uintptr

byte // alias for uint8

rune // alias for int32
     // represents a Unicode code point

float32 float64

complex64 complex128

The zero value is:
  0 for numeric types,
  false the boolean type, and
  "" (the empty string) for strings.

The expression T(v) converts the value v to the type T: // 转换
  var i int = 42
  var f float64 = float64(i)
  var u uint = uint(f)
or
  i := 42
  f := float64(i)
  u := uint(f)

6. Defer

package main

import "fmt"

func main() {
  name := "zddhub"
  defer fmt.Println(name) // 参数被存储,调用延后
  name = "hello,"
  fmt.Print(name)
  //: hello,zddhub

  // stacking defers
  fmt.Print("counting ")
  for i := 0; i < 10; i++ {
    defer fmt.Print(i, " ")
  }
  fmt.Print(" done ")
  //: hello,counting  done 9 8 7 6 5 4 3 2 1 0 zddhub
}

仔细分析第18行程序输出结果,defer按照栈的顺序,先调用后执行,并保存调用时的参数。

7. 指针

package main

import "fmt"

func main() {
  i, j := 42, 2701

  p := &i         // point to i
  fmt.Println(*p) // read i through the pointer
  *p = 21         // set i through the pointer
  fmt.Println(i)  // see the new value of i

  p = &j         // point to j
  *p = *p / 37   // divide j through the pointer
  fmt.Println(j) // see the new value of j

  var a [2]string
  a[0] = "hello"
  a[1] = "zddhub"
  pa := &a[0]

  fmt.Println(*pa)
  // fmt.Println(*(pa+1)) - 指针没有运算操作
}

8. 结构

Go没有class,只有struct

package main

import "fmt"

type Vertex struct { // 需要用type声明
  X, Y int
}

var ( // 多行声明和赋值的写法
  v1 = Vertex{1, 2}  // has type Vertex
  v2 = Vertex{X: 1}  // Y:0 is implicit
  v3 = Vertex{}      // X:0 and Y:0
  p  = &Vertex{1, 2} // has type *Vertex
)

func main() {
  fmt.Println(v1, p, v2, v3)
}

9. 内置结构

package main

import "fmt"

func main() {
  var a [2]string // 数组
  a[0] = "Hello"
  a[1] = "World"
  fmt.Println(a[0], a[1])
  fmt.Println(a)

  s := []int{2, 3, 5, 7, 11, 13} // Slices
  fmt.Println("s ==", s)
  for i := 0; i < len(s); i++ {
    fmt.Printf("s[%d] == %d\n", i, s[i])
  }
  fmt.Println("s[1:4] ==", s[1:4])
  fmt.Println("s[:3] ==", s[:3])
  fmt.Println("s[4:] ==", s[4:])

  // 创建Slices
  c := make([]int, 5)  // len(a)=5
  fmt.Println(c)
  b := make([]int, 0, 5) // len(b)=0, cap(b)=5
  b = b[:cap(b)] // len(b)=5, cap(b)=5
  b = b[1:]      // len(b)=4, cap(b)=4

  var z []int
  fmt.Println(z, len(z), cap(z))
  //: [] 0 0
  if z == nil {
    fmt.Println("nil!")
    //: nil!
  }
  z = append(z, 1)
  z = append(z, 2, 3, 4)
  fmt.Println(z)

  for i, v := range z { // range: 返回slice的index和value
    fmt.Printf("z[%d] = %d\n", i, v)
  }

  for _, v := range z { // _, 占位符, 不使用index
    fmt.Printf("%d\n", v)
  }

  for i := range z { // 不使用value,可以用_占位,或者只返回一个参数
    fmt.Printf("%d\n", i)
  }

  // Maps
  m := make(map[string]int)
  m["hello"] = 1
  m["zddhub"] = 2
  fmt.Println(m["hello"], m["zddhub"])

  var n = map[string]int{
    "hello": 1,
    "zddhub": 2, // - 需要换行时,这里的逗号不能省略
  }
  fmt.Println(n["hello"], n["zddhub"])
  delete(n, "hello")
}

如果你喜欢这篇文章,欢迎赞赏作者以示鼓励