go 基本语法

简介: go 基本语法

变量

var声明

// Go语言中推荐使用驼峰式命名
// var student_name string
var studentName string
// var StudentName string
// 声明变量
// var name string
// var age int
// var isOk bool
// 批量声明
var (
  name string // ""
  age  int    // 0
  isOk bool   // false
)
func main() {
  name = "理想"
  age = 16
  isOk = true
  // var heiheihei string
  // Go语言中非全局变量声明后必须使用,不使用就编译不过去
  fmt.Print(isOk) // 在终端中输出要打印的内容
  fmt.Println()
  fmt.Printf("name:%s\n", name) // %s:占位符 使用name这个变量的值去替换占位符
  fmt.Println(age)              // 打印完指定的内容之后会在后面加一个换行符
  // heiheihei = "嘿嘿嘿"
  // 声明变量同时赋值
  var s1 string = "whb"
  fmt.Println(s1)
  // 类型推导(根据值判断该变量是什么类型)
  var s2 = "20"
  fmt.Println(s2)
  // 简短变量声明,只能在函数里面用
  s3 := "哈哈哈"
  fmt.Println(s3)
  // s1 := "10" // 同一个作用域({})中不能重复声明同名的变量
  // 匿名变量是一个特殊的变量:_(后面学了函数再说)
}

const

// 常量
// 定义了常量之后不能修改
// 在程序运行期间不会改变的量
const pi = 3.1415926
// 批量声明常量
const (
  statusOK = 200
  notFound = 404
)
// 批量声明常量时,如果某一行声明后没有赋值,默认就和上一行一致
const (
  n1 = 100
  n2
  n3
)
// iota
const (
  a1 = iota // 0
  a2        // 1
  a3        // 2
)
const (
  b1 = iota // 0
  b2 = iota // 1
  _  = iota // 2
  b3 = iota // 3
)
// 插队
const (
  c1 = iota // 0
  c2 = 100  // 100
  c3 = iota // 2
  c4
)
// 多个常量声明在一行
const (
  d1, d2 = iota + 1, iota + 2 // d1:1 d2:2
  d3, d4 = iota + 1, iota + 2 // d3:2 d4:3
)
// 定义数量级
const (
  _  = iota
  KB = 1 << (10 * iota)
  MB = 1 << (10 * iota)
  GB = 1 << (10 * iota)
  TB = 1 << (10 * iota)
  PB = 1 << (10 * iota)
)
func main() {
  // pi = 123
  // fmt.Println("n1:", n1)
  // fmt.Println("n2:", n2)
  // fmt.Println("n3:", n3)
  // fmt.Println("a1:", a1)
  // fmt.Println("a2:", a2)
  // fmt.Println("a3:", a3)
  // fmt.Println("b1:", b1)
  // fmt.Println("b2:", b2)
  // fmt.Println("b3:", b3)
  // fmt.Println("c1:", c1)
  // fmt.Println("c2:", c2)
  // fmt.Println("c3:", c3)
  // fmt.Println("c4:", c4)
  fmt.Println("d1:", d1)
  fmt.Println("d2:", d2)
  fmt.Println("d3:", d3)
  fmt.Println("d4:", d4)
}

int

// 整型
func main() {
  // 十进制
  var i1 = 101
  fmt.Printf("%d\n", i1)
  fmt.Printf("%b\n", i1) // 把十进制数转换成二进制
  fmt.Printf("%o\n", i1) // 把十进制数转换成八进制
  fmt.Printf("%x\n", i1) // 把十进制数转换成十六进制
  // 八进制
  i2 := 077
  fmt.Printf("%d\n", i2)
  // 十六进制
  i3 := 0x1234567
  fmt.Printf("%d\n", i3)
  // 查看变量的类型
  fmt.Printf("%T\n", i3)
  // 声明int8类型的变量
  i4 := int8(9) // 明确指定int8类型,否则就是默认为int类型
  fmt.Printf("%T\n", i4)
}

float

package main
import "fmt"
// 浮点数
func main() {
  // math.MaxFloat32 // float32最大值
  f1 := 1.23456
  fmt.Printf("%T\n", f1) // 默认Go语言中的小数都是float64类型
  f2 := float32(1.23456)
  fmt.Printf("%T\n", f2) // 显示声明float32类型
  // f1 = f2                // float32类型的值不能直接复赋值给float64类型的变量
}

bool

package main
import "fmt"
// 布尔值
func main() {
  b1 := true
  var b2 bool // 默认是false
  fmt.Printf("%T\n", b1)
  fmt.Printf("%T value:%v\n", b2, b2)
}

fmt

package main
import "fmt"
// fmt占位符
func main() {
  var n = 100
  // 查看类型
  fmt.Printf("%T\n", n)
  fmt.Printf("%v\n", n)
  fmt.Printf("%b\n", n)
  fmt.Printf("%d\n", n)
  fmt.Printf("%o\n", n)
  fmt.Printf("%x\n", n)
  var s = "Hello 沙河!"
  fmt.Printf("字符串:%s\n", s)
  fmt.Printf("字符串:%v\n", s)
  fmt.Printf("字符串:%#v\n", s)
}

string

package main
import (
  "fmt"
  "strings"
)
// 字符串
func main() {
  // \ 本来是具有特殊含义的,我应该告诉程序我写的\就是一个单纯的\
  path := "'D:\\Go\\src\\code.oldboyedu.com\\studygo\\day01'"
  fmt.Println(path)
  s := "I'm ok"
  fmt.Println(s)
  // 多行的字符串
  s2 := `
世情薄
        人情恶
    雨送黄昏花易落
  `
  fmt.Println(s2)
  s3 := `D:\Go\src\code.oldboyedu.com\studygo\day01`
  fmt.Println(s3)
  // 字符串相关操作
  fmt.Println(len(s3)) // ?
  // 字符串拼接
  name := "理想"
  world := "大帅比"
  ss := name + world
  fmt.Println(ss)
  ss1 := fmt.Sprintf("%s%s", name, world)
  // fmt.Printf("%s%s", name, world)
  fmt.Println(ss1)
  // 分隔
  ret := strings.Split(s3, "\\")
  fmt.Println(ret)
  // 包含
  fmt.Println(strings.Contains(ss, "理性"))
  fmt.Println(strings.Contains(ss, "理想"))
  // 前缀
  fmt.Println(strings.HasPrefix(ss, "理想"))
  // 后缀
  fmt.Println(strings.HasSuffix(ss, "理想"))
  s4 := "abcdeb"
  fmt.Println(strings.Index(s4, "c"))
  fmt.Println(strings.LastIndex(s4, "b"))
  // 拼接
  fmt.Println(strings.Join(ret, "+"))
}

byte

package main
import "fmt"
// byte和rune类型
// Go语言中为了处理非ASCII码类型的字符 定义了新的rune类型
func main() {
  s := "Hello沙河사샤"
  // len()求得是byte字节的数量
  n := len(s) // 求字符串s的长度,把长度保存到变量n中
  fmt.Println(n)
  // for i := 0; i < len(s); i++ {
  //  // fmt.Println(s[i])
  //  fmt.Printf("%c\n", s[i]) // %c:字符
  // }
  // for _, c := range s { // 从字符串中拿出具体的字符
  //  fmt.Printf("%c\n", c) // %c:字符
  // }
  // "Hello" => 'H' 'e' 'l' 'l' 'o'
  // 字符串修改
  s2 := "白萝卜"      // => '白' '萝' '卜'
  s3 := []rune(s2) // 把字符串强制转换成了一个rune切片
  s3[0] = '红'
  fmt.Println(string(s3)) // 把rune切片强制转换成字符串
  c1 := "红"
  c2 := '红' // rune(int32)
  fmt.Printf("c1:%T c2:%T\n", c1, c2)
  c3 := "H"       // string
  c4 := byte('H') // byte(uint8)
  fmt.Printf("c3:%T c4:%T\n", c3, c4)
  fmt.Printf("%d\n", c4)
  // 类型转换
  n1 := 10 // int
  var f float64
  f = float64(n1)
  fmt.Println(f)
  fmt.Printf("%T\n", f)
}

基本程序结构

条件和循环

if

package main
import "fmt"
// if条件判断
func main() {
  // age := 19
  // if age > 18 { // 如果 age > 18 就执行这个{}中的代码
  //  fmt.Println("澳门首家线上赌场开业啦!")
  // } else { // 否则就执行这个{}中的代码
  //  fmt.Println("改写暑假作业啦!")
  // }
  // 多个判断条件
  // if age > 35 {
  //  fmt.Println("人到中年")
  // } else if age > 18 {
  //  fmt.Println("青年")
  // } else {
  //  fmt.Println("好好学习!")
  // }
  // 作用域
  // age变量此时只在if条件判断语句中生效
  if age := 19; age > 18 { // 如果 age > 18 就执行这个{}中的代码
    fmt.Println("澳门首家线上赌场开业啦!")
  } else { // 否则就执行这个{}中的代码
    fmt.Println("改写暑假作业啦!")
  }
  // fmt.Println(age) // 在这里是找不到age
}
n:=0
for n<5{
    n++
    fmt.Println(n)
}

无限循环

n:=0
for{
n++
fmt.Println(n)
}

switch与其它语言的区别

1.条件表达式不限制为常量或者证书;

2.单个case中,可以出现多个结果选项,使用逗号分隔;

3.与C语言等规则相反,go语言不需要用break来明确退出一个case;

4.可以不设定 switch之后的条件表达式,在此种情况下,整个switch结构与多个if else 的逻辑作用相同

func TestSwitchMultiCase(t *testing.T){
  for i:=0;i<5;i++{
    switch i {
    case 0, 2:
      t.Log("Even")
    case 1,3:
      t.Log("Odd")
    default:
      t.Log("it is not 0-3")
    }
  }
}
func TestSwitchCaseCondition(t*testing.T){
  for i:=0;i<5;i++{
    switch  {
    case i%2==0:
      t.Log("Even")
    case i%2==1:
      t.Log("Odd")
    default:
      t.Log("unknown")
    }
  }

常用集合

数组和切片

var a [3]int//声明并初始化为默认值0
a[0]=1
b:=[3]int{1,2,3}//声明同时初始化
c:=[2][2]int{{1,2},{3,4}}//多维数组初始化

数组的初始化与遍历

import "testing"
func TestArrayInit(t *testing.T){
  var arr[3]int//初始化默认结果为0
  arr1:=[4]int{1,2,3,4}//
  arr2:=[...]int{1,3,4,5}
  t.Log(arr[1],arr[2])
  t.Log(arr1[1],arr2[1])
}
func TestArrayTravel(t *testing.T){
  arr3 := [...]int{1,2,3,4,5}
  for i:=0;i<len(arr3);i++{
    t.Log(arr3[i])
  }
  for idx,e:=range arr3{
    t.Log(idx,e)
  }
}

数组截取

a[开始索引(包含),结束索引(不包含)]

a:=[...]int{1,2,3,4,5,60}

a[1:2]//2

a[1:3]//2,3

a[1:len(a)]//2 3 4 5

a[1:]//2,3,4,5,60

a[:3]//1,2,3

切片内部结构

切片内部是一个结构体

func TestSliceGrowing(t *testing.T){
  s:=[]int{}
  for i:=0;i<10;i++{
    s = append(s, i)
    t.Log(len(s),cap(s))
  }
}
=== RUN   TestSliceGrowing
--- PASS: TestSliceGrowing (0.00s)
    slice_test.go:24: 1 1
    slice_test.go:24: 2 2
    slice_test.go:24: 3 4
    slice_test.go:24: 4 4
    slice_test.go:24: 5 8
    slice_test.go:24: 6 8
    slice_test.go:24: 7 8
    slice_test.go:24: 8 8
    slice_test.go:24: 9 16
    slice_test.go:24: 10 16
PASS

共享连续存储控件

func TestSliceShareMemory(t *testing.T){
  year:=[]string{"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"}
  Q2:=year[3:6]
  t.Log(Q2,len(Q2),cap(Q2))
  summer :=year[5:8]
  t.Log(summer,len(summer),cap(summer))
}
=== RUN   TestSliceShareMemory
--- PASS: TestSliceShareMemory (0.00s)
    slice_test.go:30: [Apr May Jun] 3 9
    slice_test.go:32: [Jun Jul Aug] 3 7
PASS

数组 vs 切片

1.容量是否可伸缩

数组不可伸缩

2.是否可以进行比较

数组长度相同可以比较,slice 只能与nil进行比较 不可以比较两个slice

Map声明 元素访问及遍历

m:=map[string]int{"one":1,"two":2,"three":3}

m1:=map[string]int{}

m1["one"]=1

m2:=make(map[string]int, 10/Initial Capacity/)//为什么不初始化len?

判断map里面的值是否存在
func TestAccessNotExistingKey(t *testing.T){
  m1:=map[int]int{}
  t.Log(m1[1])
  m1[2]=0
  t.Log(m1[2])
  m1[3]=0
  if v,ok:=m1[3];ok{
    t.Log("key 3 is ",v)
  }else{
    t.Log("key 3 is not existing")
  }
}

map 元素的访问

与其他主要编程语言的差异

在访问key不存在时, 仍然会返回零值,不能通过返回nil来判断元素是否存在

if v,ok:=m["four"];ok{
    t.log("four",v)
}
else{
    t.Log("Not existing")
}

map元素的遍历

m:=map[string]int{"one":1,"two":2,"three":3}
for k,v :range m{
    t.Log(k,v)
}
func TestTravelMap(t*testing.T){
  m:=map[string]int{"one":1,"two":2,"three":3}
  for k,v:=range m{
    t.Log(k,v)
  }
}

Map 与工厂模式,在go语言中实现工厂模式

map与工厂模式

  • Map的value可以是一个方法
  • 与Go的Dock type接口方式一起,可以方便的实现单一方法对象的工厂模式
//value是一个方法
package _map
import "testing"
func TestMapWithFunVlaue(t *testing.T){
  m:=map[int]func(op int)int{}
  m[1]=func(op int)int{return op}
  m[2]=func(op int)int{return op*op}
  m[3]=func(op int)int{return op*op*op}
  t.Log(m[1](2),m[2](2),m[3](2))
}

实现Set

Go的内置集合中没有set实现,可以map[type]bool

1.元素的唯一性

2.基本操作

  • 添加元素
  • 判断元素是否存在
  • 删除元素
  • 元素个数
func TestMapForSet(t*testing.T){
  mySet:=map[int]bool{}
  mySet[1]=true
  n:=1
  if mySet[n]{
    t.Logf("%d is existing",n)
  }else{
    t.Logf("%d is not existing",n)
  }
  mySet[3]=true
  delete(mySet,1)
  n=1
  if mySet[n]{
    t.Logf("%d is existing",n)
  }else{
    t.Logf("%d is not existing",n)
  }
}

字符串

与其它主要编成语言的差异

1.string 是数据类型,不是引用类型或者指针类型

2.string是只读的byte slice len函数可以计算它所包含的byte数

3.string的byte数组可以存放任何数据

Unicode 与UTF8

1.Unicode是一种字符集(code point)

2.UTF8是unicode的存储实现(转换为字节序列的规则)

编码与存储

字符 "中"

Unicode 0x4E2D

UTF-8 0xE4B8AD

string/[]byte [0xE4,0xB8,0xAD]

常用的字符串函数

目录
相关文章
|
2月前
|
Java 编译器 Go
Go to Learn Go之基础语法
Go to Learn Go之基础语法
18 0
|
5月前
|
存储 Java Go
|
5月前
|
编译器 Go 开发者
|
6月前
|
Java 编译器 Go
【字节跳动青训营】后端笔记整理-1 | Go语言入门指南:基础语法和常用特性解析(一)
本文主要梳理自第六届字节跳动青训营(后端组)-Go语言原理与实践第一节(王克纯老师主讲)。
157 1
|
6月前
|
编译器 Go
Go 语言基础语法
Go 语言基础语法
44 1
|
5月前
|
Go
go基础语法结束篇 ——函数与方法
go基础语法结束篇 ——函数与方法
|
5月前
|
编译器 Go 数据安全/隐私保护
go语言入门之路——基础语法
go语言入门之路——基础语法
|
5月前
|
存储 安全 Java
【Go语言精进之路】Go语言基础:基础语法概览
【Go语言精进之路】Go语言基础:基础语法概览
50 0
|
6月前
|
存储 Go C语言
【GO基础】GO基础语法一
【GO基础】GO基础语法一
|
5月前
|
Java Go Scala