Golang基础语法| 青训营笔记

96 阅读2分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第1篇笔记

第一个当然是 hello,world啦

package main
import "fmt"

func main(){
   fmt.Println("hello,world")
}

  • Go语言类c++风格
  • 每个Go程序必须包含一个main包以及一个main()函数。main()作为整个程序的入口,在程序执行时最先被执行。
  • fmt包提供格式化文本和读入格式文本的函数,提供不同打印函数变体。fmt.Println()会整洁的打印输入的内容,fmt.Printf()使用占位符来提供良好的格式化输出控制能力。
  • 程序没有分号,import语句也不用逗号分割,代码缩进仅仅为了提高代码可读性。从技术层面讲,Go的语句是以分号分隔,但这些是编译器自动添加,不需手动输入
  • Go语言的函数和方法以关键字func定义,但main包里的main函数比较特别,既没有参数也没有返回值,当main.main()运行完毕,程序会自动终止并向操作系统返回0.

基础语法

  • 使用 ":=" 进行声明变量并赋值操作,不需要 var 关键字;
    使用 "=" 进行赋值操作,需要先 var 声明
    定义常量则是将 var 改成 const

      var a = 10
      var b
      b = 10
    
      d := 100
    
      const s string = "constant"
      cosnt h = 5e10
    
  • 循环结构之后for循环
    if 之后没有括号,但必须接上大括号;

      import "fmt"
    
      if 7%2 == 0 {
          fmt.Println("7 is even")
      }
    
  • 另外还有一个改版,先执行 statement, 然后再判断 condition

      if statement; condition {
    
      }
      if num := 9; num < 0 {
          fmt.Println(num, "is negative")
      } else if num < 10 {
          fmt.Println(num, "has 1 digit")
      }
    
  • switch 语句,不同于 C & C++, 会case一旦对上,会自动break

a := 2
switch a {
case 1:
     fmt.Println
}
  • 使用切片,作为可变长度的数组
s := make([]string, 3)

  • 变量类型后置
var s string

基本类型语法

package main

import (
   "fmt"
   "math"
)

func main(){
   var a = "initial"

   var b , c int = 1,2
   var d=true
   var e float64
   f := float32(e)
   g := a+"foo"
   fmt.Println(a,b,c,d,e,f)
   //initial 1 2 true 0 0

   fmt.Println(g)
//initialfoo

   const s string ="constant"
   const h = 500000000
   const i = 3e20/h
   fmt.Println(s,h,i,math.Sin(h),math.Sin(i))
   //constant 500000000 6e+11 -0.28470407323754404 0.7591864109375384

}
复制代码
  • 操作符 := 快速变量声明。可以同时声明并初始化一个变量,不必声明一个具体类型的变量,Go语言可以从其初始化值推导其类型。go是强类型语言。
  • 常量使用const声明,变量使用var声明,也可以快捷变量声明。
  • var/const a int/float=
  • 变量e没有显示初始化,会赋零值,字符串会默认为空。
  • Go语言提供了大量内置的数值类型。不能在不同的类型之间进行二进制数值运算或比较操作。无类型的数值常量可以兼容表达式中任何类型的数值。将类型转换成最大的类型防止精度丢失以进行运算。type(value)
  • 3e20是科学计数法 3*10^20
  • Math.Sin(x) 以弧度为单位的x的正弦值

if语句

package main

import "fmt"

func main(){
   if 7%2==0 {
      fmt.Println("7 is even")
   }else {
      fmt.Println("7 is odd")
   }
//if optionalStatement1;booleanExpression1 {}
   if num:=8;num<0 {
      fmt.Println(num,"is negetive")
   }else if num<10{
      fmt.Println(num,"has 1 digit")
   }
}
复制代码
  • if语句的大括号是强制性的,条件判断中的分号只有在可选语句optionalStatement出现的情况下需要。可选语句只能是表达式、发送到通道(使用<-操作符)、增减值语句、赋值语句或短变量声明语句。如果变量是在一个可选的声明语句中创建的(使用:=操作符创建),他们的作用于会从声明处扩展到if语句的完成处,他们在声明他们的if或elseif语句以及相应分支中一直存在,直到if语句的末尾。
  • 第一个if语句的num变量扩展到了if...elseif...语句中,因此他们在每一个分支中都是可见的。

for循环

package main

import "fmt"

func main(){
   i:=1
  //for booleanExpression{block}
  for{
  
      fmt.Println("loop")
      break
   }
   // for optionalPreStatement;booleanExpress;optionalPostStatement
   for j:=7;j<9;j++{
      fmt.Println(j)
   }
   for n:=9;n<5;n++ {
      if n%2==0 {
         continue
      }
      fmt.Println(n)
   }
   for i<=3 {
      fmt.Println(i)
      i=i+1
   }
}
复制代码

switch循环

package main

import (
   "fmt"
   "time"
)

func main(){
   a := 2
   //switch optionalStatement{
   switch a {
   //case expressionList1:
       //block
   case 1:
      fmt.Println("one")

   case 2:
      fmt.Println("two")
   case 3:
      fmt.Println("three")
   //default:bloakD
   default:
      fmt.Println("other")
}
   t:=time.Now()
   switch  {
   case t.Hour()<12:
      fmt.Println("1")
   default:
      fmt.Println("2")
   }

   }
复制代码
  • 不同于c和java,go的switch语句不会自动向下贯穿,因此不必在每个case字句末尾添加break语句,需要case

语句向下贯穿时可以显式调用fallthrough

  • 没有可选的表达式语句,编译器会把表达式语句设为true。意味着case语句的每一个表达式都必须计算为布尔类型。

字符串切片

package main

import "fmt"

func main(){
   s:=make([]string,3)
   s[0]="a"
   s[1]="b"
   s[2]="c"
   fmt.Println("get:",s[2])
   fmt.Println("len:",len(s))

   s=append(s,"d")
   s=append(s,"e","f")
   //[a b c d e f]
   fmt.Println(s)

   c:=make([]string,len(s))
   copy(c,s)
   //[a b c d e f]
   fmt.Println(c)
//[c d e]
   fmt.Println(s[2:5])
  // [a b c d e]
   fmt.Println(s[:5])
   //[c d e f]
   fmt.Println(s[2:])

   good := []string{"g","o","o","d"}
   fmt.Println(good)

}
复制代码
  • [2:5] 从2-4
  • [:5] 从0-4
  • [2:] 从2到结尾 len(s)-1
  • 切片 从开始到结束为止 不包含结束位置
make([]T,len)//长度为切片长度
make([]T,len,cap)//same as make([]T,cap)[:len] 长度为切片容量
复制代码
  • 内置函数make创建指定元素类型、长度和容量的slice

    • 创建一个隐藏的初始化为零值的数组,然后返回一个引用该隐藏数组的切片。
    • 在底层,make创建了一个匿名的数组变量,返回一个slice。只有通过返回的slice才能引用底层匿名的数组遍历。
    • 一个切片是一个隐藏数组的引用
  • 对于append函数,每次调用会检测slice底层数组是否有足够容量来保存新添加的元素。如果空间足够,直接扩展slice(在原有的底层数组上),将新添加的元素复制到新扩展的空间,并返回slice。输入和输出共享相同的底层数组。

    • 如果没有足够的增长空间,会先分配一个足够大的slice用于保存新的结果,将输入复制到新的空间,然后添加一个新元素。输入和输出引用的是不同的底层数组。
    • 内置的append函数可能使用比appendInt更复杂的内存扩展策略。因此通常不知道append是否导致了内存的重新分配,也不能确定原始slice和新的slice引用的是否是相同的底层数组空间。通常是将append返回的结果直接赋值给输入的slice变量。
  • 内置的copy元素可以方便的将一个slice复制到另一个相同类型的slice。copy的第一个参数是要复制的目前slice,第二个参数是源slice。两个slice可以共享一个底层数组,有重叠也没问题。copy函数将返回成功赋值的元素的个数(这里没有用到),等于两个slice中较小的长度,所以无须担心复制会超出目标slice的范围。

map

package main

import "fmt"

func main(){
   m:=make(map[string]int)
   m["one"]=1
   m["two"]=2
   //map[one:1 two:2]
   fmt.Println(m)
   //2
   fmt.Println(len(m))
   //1
   fmt.Println(m["one"])
   //0
   fmt.Println(m["unknow"])

   r,ok := m["unknow"]
   //0 false
   fmt.Println(r,ok)

   delete(m,"one")

   m2:=map[string]int{"one":1,"two":2}
   var m3 = map[string]int{"one":1,"two":2}
   fmt.Println(m2,m3)
}
复制代码
  • map保存键值对的无序结合。键唯一

  • m[k]=v 用键k来将值v赋值给映射m。如果映射m中的k已存在,将之前的值丢弃。

  • v,found := m[k] 从映射m中取得键相对应的值并将其赋值给v,并将found的值赋值为true。如果k在映射中不存在,则将映射类型为0值赋值给v,并将found的值赋值为false。

  • delete(m,k) 将键k及相关的值从映射m中删除,如果k不存在则安全地不执行任何操作

  • v:=m[k] 从映射m中取得键k相对应的值并将其赋值给v。如果k在映射中不存在,将映射类型的0值赋值给v。类似于Java的getOrDefault(k,0)

  • len(m) 返回映射m中项("键/值"对)的数目

  • map[KeyType]ValueType{key1:value1,key2:value2...}

  • 用make()创建的映射得到的是空的映射,指定容量就会预先申请到足够的内存,随着加入的项越来越多映射会自动扩容。

    • make(map[KeyType]ValueType)

函数

  • golang中变量后置
package mai

import "fmt"

type Books struct {
   title string
   author string
   subject string
   book_id int
}


func main() {

    // 创建一个新的结构体
    fmt.Println(Books{"Go 语言""www.runoob.com""Go 语言教程"6495407})

    // 也可以使用 key => value 格式
    fmt.Println(Books{title: "Go 语言", author: "www.runoob.com", subject: "Go 语言教程", book_id: 6495407})

    // 忽略的字段为 0 或 空
   fmt.Println(Books{title: "Go 语言", author: "www.runoob.com"})
}

输出结果为:

{Go 语言 www.runoob.com Go 语言教程 6495407}
{Go 语言 www.runoob.com Go 语言教程 6495407}
{Go 语言 www.runoob.com  0}