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

推荐订阅源

SecWiki News
SecWiki News
I
InfoQ
The Cloudflare Blog
人人都是产品经理
人人都是产品经理
博客园 - Franky
T
Tailwind CSS Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
量子位
博客园_首页
罗磊的独立博客
V
V2EX
李成银的技术随笔
大猫的无限游戏
大猫的无限游戏
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
True Tiger Recordings
Vercel News
Vercel News
Cyberwarzone
Cyberwarzone
Cisco Talos Blog
Cisco Talos Blog
F
Fox-IT International blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
M
Microsoft Research Blog - Microsoft Research
Know Your Adversary
Know Your Adversary
爱范儿
爱范儿
The Register - Security
The Register - Security
G
Google Developers Blog
The Hacker News
The Hacker News
Malwarebytes
Malwarebytes
S
Securelist
博客园 - 三生石上(FineUI控件)
Jina AI
Jina AI
T
Threat Research - Cisco Blogs
T
The Exploit Database - CXSecurity.com
S
SegmentFault 最新的问题
博客园 - 叶小钗
F
Fortinet All Blogs
Apple Machine Learning Research
Apple Machine Learning Research
宝玉的分享
宝玉的分享
博客园 - 聂微东
T
Threatpost
博客园 - 【当耐特】
D
Docker
P
Privacy & Cybersecurity Law Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
G
GRAHAM CLULEY
V
Visual Studio Blog
C
Cisco Blogs
IT之家
IT之家
S
Security Archives - TechRepublic
Latest news
Latest news
阮一峰的网络日志
阮一峰的网络日志

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语法简略 - 方法和接口 Go语法简略 - goroutine 大牛 | 轻松科研 未来这几年 为 Android Studio 创建图标 Shell Git Vim 金庸答百问 论拖延症 Flex, A fast scanner generator 有理想的人 从虚拟到现实 常用视频转接口 Recognizer configuration on CentOS 整个世界清静了 《Python源码剖析》读书笔记
Go语法简略 - 基础篇
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")
}

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