【GO基础】GO基础语法一

简介: 【GO基础】GO基础语法一

一、编写第一个Go程序

1、基本程序结构

package main //包,表名代码所在的模块(包)

import "fmt" //引入代码依赖

//功能实现
func main(){
    fmt.Println("Hello,World!")

}

2、应用程序入口

  1. 必须是main包 package main
  2. 必须是main方法 func main()
  3. 文件名不一定是main.go

3、退出返回值

与其他主要变成语言的差异

  • Go中的main函数不支持任何返回值

  • 通过os.Exit 来返回状态


4、获取命令行参数

与其他主要变成语言的差异

  • main函数不支持传入参数
func main~~(arg []string)~~
  • 在程序中直接通过os.Args获取命令行参数

二、变量,常量以及与其他语言的差异

1、编写测试程序

  1. 源文件以_test结尾:xxx_test.go
  2. 测试方法以Test开头:func TestXXX(t *testing.T){}
package test

import (
    "log"
    "testing"
)

func TestFirstTry(T *testing.T){

    log.Print("My first try!")
}

2、实现Fibonacci数列

1,1,2,3,5,8,13,…

package fib

import (
  "testing"
)

// TestFibList 是测试斐波那契数列生成函数的单元测试函数
func TestFibList(t *testing.T) {
  var a int = 1
  var b int = 1

  // 另一种变量声明方式:
  // var (
  //     a int = 1
  //     b     = 1
  // )

  // 或者使用短变量声明方式:
  // a := 1
  // b := 1

  // 输出变量 a 的值
  t.Log(a)

  // 循环生成斐波那契数列的前5个数并输出
  for i := 0; i < 5; i++ {
    // 输出变量 b 的值
    t.Log(b)

    // 交换 a 和 b 的值,生成下一个斐波那契数
    tmp := a
    a = b
    b = tmp + a
  }
}

3、变量赋值

与其他主要变成语言的差异

  • 赋值可以进行自动类型推断
  • 在一个赋值语句中可以对多个变量进行同时赋值
package fib

import (
  "testing"
)

// TestExChange 是测试变量交换函数的单元测试函数
func TestExChange(t *testing.T) {
  // 初始化两个变量 a 和 b 的值
  a := 1
  b := 2

    //temp :=a  
  //a=b
  //b=temp

  // 使用短变量声明方式,同时交换 a 和 b 的值
  // 在 Go 中,可以通过这种方式轻松地实现两个变量的值交换
  a, b = b, a

  // 输出交换后的变量值
  t.Log(a, b)
}

输出结果:

4、常量定义

与其他主要变成语言的差异

快速设置连续值

iota枚举

Go里面有一个关键字iota,这个关键字用来声明enum的时候采用,它默认开始值是0,const中每增加一行加1:

package constan_test

import "testing"

// 第一个常量组,使用 iota 枚举星期几
const (
  Monday    = iota + 1
  Tuesday
  Wednesday
)

// 第二个常量组,使用 iota 创建一组表示文件权限的常量
const (
  Readable  = 1 << iota // 位运算左移,表示可读
  Writable              // 位运算左移,表示可写
  Executable            // 位运算左移,表示可执行
)

// TestConstanTry 是测试星期几常量的单元测试函数
func TestConstanTry(t *testing.T) {
  // 输出星期几的常量值
  t.Log("星期一:", Monday)
  t.Log("星期二:", Tuesday)
  t.Log("星期三:", Wednesday)
}

// TestConstanTry1 是测试文件权限常量的单元测试函数
func TestConstanTry1(t *testing.T) {
  //a:=7 // 二进制表示为 0111 TRUE TRUE  TRUE 
  a := 1 // 二进制表示为 0001 true false false

  // 使用位运算检查文件权限
  t.Log("可读:", a&Readable == Readable) 
  t.Log("可写:", a&Writable == Writable)
  t.Log("可执行:", a&Executable == Executable)
}

三、数据类型

数据类型 描述 示例
int 有符号整数类型,大小取决于计算机架构,常用于表示整数。 var x int = 10
int8 有符号8位整数类型,范围为-128到127。 var x int8 = 127
int16 有符号16位整数类型,范围为-32768到32767。 var x int16 = -300
int32 有符号32位整数类型,范围为-2147483648到2147483647。 var x int32 = 100000
int64 有符号64位整数类型,范围为-9223372036854775808到9223372036854775807。 var x int64 = -9223372036854775808
uint 无符号整数类型,大小取决于计算机架构,常用于表示正整数。 var x uint = 10
uint8 无符号8位整数类型,范围为0到255。 var x uint8 = 255
uint16 无符号16位整数类型,范围为0到65535。 var x uint16 = 65535
uint32 无符号32位整数类型,范围为0到4294967295。 var x uint32 = 4294967295
uint64 无符号64位整数类型,范围为0到18446744073709551615。 var x uint64 = 18446744073709551615
float32 32位浮点数类型,可表示小数。 var x float32 = 3.14
float64 64位浮点数类型,可表示小数。 var x float64 = 3.14
complex64 由两个32位浮点数表示的复数类型。 var x complex64 = 3 + 4i
complex128 由两个64位浮点数表示的复数类型。 var x complex128 = 3 + 4i
byte uint8 的别名,常用于表示ASCII字符。 var x byte = ‘A’
rune int32 的别名,常用于表示Unicode字符。 var x rune = ‘你’
string 字符串类型,表示一串字符。 var x string = “Hello”
bool 布尔类型,表示真或假。 var x bool = true
array 数组类型,固定大小的元素序列。 var x [3]int = [3]int{1, 2, 3}
slice 切片类型,可变大小的元素序列。 var x []int = []int{1, 2, 3}
map 映射类型,存储键值对的无序集合。 var x map[string]int = map[string]int{“a”: 1, “b”: 2}
struct 结构体类型,自定义的复合数据类型。 type Person struct {Name string; Age int}

1、类型转化

与其他主要变成语言的差异

  1. Go语言不允许隐式类型转换
  2. 别名和原有类型也不能进行隐式类型转换

2、类型的预定义值

math 包提供了一些常用类型的预定义值,包括整数、浮点数等。以下是三个例子:

  1. math.MaxInt64
  2. math.MaxFloat64
  3. math.MaxUint32

package math_constants

import (
    "fmt"
    "math"
)

func ExampleMaxInt64() {
    // 输出 int64 类型的最大值
    fmt.Printf("int64 类型的最大值:%d\n", math.MaxInt64)
}
func ExampleMaxFloat64() {
  // 输出 float64 类型的最大值
  fmt.Printf("float64 类型的最大值:%f\n", math.MaxFloat64)
}
func ExampleMaxUint32() {
  // 输出 uint32 类型的最大值
  fmt.Printf("uint32 类型的最大值:%d\n", math.MaxUint32)
}

func main() {
    ExampleMaxInt64()
    ExampleMaxFloat64()
    ExampleMaxUint32()
}

这些预定义值对于处理数值边界和范围非常有用。

3、指针类型

与其他主要变成语言的差异

  1. 不支持指针运算

在 Go 语言中,指针的使用受到一些限制,其中最明显的一点是不支持指针运算。以下是一个简单的例子,说明了指针运算在 Go 中是不允许的:

package pointer_test

import "testing"

// TestPointerArithmetic 是测试指针运算的单元测试函数
func TestPointerArithmetic(t *testing.T) {
  // 定义一个整数变量 x,并赋值为 10
  x := 10

  // 定义一个指向整数的指针变量 p,指向 x 的内存地址
  p := &x

  // 尝试进行指针运算(不允许的操作),这将导致编译错误
  // p = p + 1  // 这行代码会导致编译错误

  // 输出 x 的值和指针变量 p 的值
  t.Logf("x 的值:%d,指针变量 p 的值:%p", x, p)
}

在这个例子中,尝试进行指针运算 p = p + 1 会导致编译错误,因为在 Go 中不允许直接对指针进行加法或减法运算。

  1. string是值类型,其默认的初始化值为空字符串,而不是null

在 Go 中,string 是一种特殊的值类型,它代表不可变的字符序列。string 的默认初始化值是空字符串而不是 null。以下是一个示例:

package string_test

import "testing"

// TestStringInitialization 是测试 string 初始化的单元测试函数
func TestStringInitialization(t *testing.T) {
    // 声明一个字符串变量 s,其默认初始化值为空字符串
    var s string

    // 输出字符串变量 s 的值
    t.Logf("字符串变量 s 的值:%q", s)
}

在这个例子中,s 是一个字符串变量,由于没有显式赋值,它的默认初始化值是空字符串。通过 %q 格式化符输出字符串时,如果字符串为空,会显示为空字符串而不是 null

四、运算符

1、算数运算符

运算符 描述 示例
+ 加法 a + b
- 减法 a - b
* 乘法 a * b
/ 除法 a / b
% 求余 a % b
++ 自增 a++++a
自减 a––a

Go语言没有前置的++,–(++a)

以下是一个使用算术运算符的简单示例:

package arithmetic_operators

import "fmt"

func main() {
  // 定义两个整数变量
  a := 10
  b := 5

  // 加法
  sum := a + b
  fmt.Printf("加法结果:%d\n", sum)

  // 减法
  difference := a - b
  fmt.Printf("减法结果:%d\n", difference)

  // 乘法
  product := a * b
  fmt.Printf("乘法结果:%d\n", product)

  // 除法
  quotient := a / b
  fmt.Printf("除法结果:%d\n", quotient)

  // 求余
  remainder := a % b
  fmt.Printf("求余结果:%d\n", remainder)

  // 自增
  a++
  fmt.Printf("自增后的值:%d\n", a)

  // 自减
  b--
  fmt.Printf("自减后的值:%d\n", b)
}

2、比较运算符

运算符 描述 示例
== 相等 a == b
!= 不相等 a != b
< 小于 a < b
> 大于 a > b
<= 小于等于 a <= b
>= 大于等于 a >= b
package comparison_operators

import "fmt"

func main() {
  // 定义两个整数变量
  a := 10
  b := 5

  // 相等
  equal := a == b
  fmt.Printf("相等:%t\n", equal)

  // 不相等
  notEqual := a != b
  fmt.Printf("不相等:%t\n", notEqual)

  // 小于
  lessThan := a < b
  fmt.Printf("小于:%t\n", lessThan)

  // 大于
  greaterThan := a > b
  fmt.Printf("大于:%t\n", greaterThan)

  // 小于等于
  lessThanOrEqual := a <= b
  fmt.Printf("小于等于:%t\n", lessThanOrEqual)

  // 大于等于
  greaterThanOrEqual := a >= b
  fmt.Printf("大于等于:%t\n", greaterThanOrEqual)
}

3、用==比较数组

  • 数组的维数必须相同。
  • 数组中元素的个数必须相同。
  • 数组中的每个元素都必须相等。
package test

import (
  "fmt"
  "testing"
)

func TestArrayComparison(t *testing.T) {
  // 定义两个数组
  array1 := [3]int{1, 2, 3}
  array2 := [3]int{1, 2, 3}
  array3 := [3]int{4, 5, 6}

  // 使用 == 比较数组
  equal1 := array1 == array2
  equal2 := array1 == array3

  // 输出比较结果
  fmt.Printf("array1 是否等于 array2:%t\n", equal1)
  fmt.Printf("array1 是否等于 array3:%t\n", equal2)
}


4、逻辑运算符

运算符 描述 示例
&& 逻辑与 a && b
|| 逻辑或 a || b
! 逻辑非 !a
func TestLogical(t *testing.T) {
  // 定义两个布尔变量
  isTrue := true
  isFalse := false

  // 逻辑与
  andResult := isTrue && isFalse
  fmt.Printf("逻辑与结果:%t\n", andResult)

  // 逻辑或
  orResult := isTrue || isFalse
  fmt.Printf("逻辑或结果:%t\n", orResult)

  // 逻辑非
  notResult := !isTrue
  fmt.Printf("逻辑非结果:%t\n", notResult)
}

5、位运算符

运算符 描述 示例
& 位与 a & b
| 位或 a | b
^ 位异或 a ^ b
<< 左移 a << b
>> 右移 a >> b
&^ 位清空 (AND NOT) a &^ b
func TestBitwiseOperators(t *testing.T) {
    // 定义两个整数变量
    a := 5    // 二进制: 0101
    b := 3    // 二进制: 0011

    // 位与
    andResult := a & b
    fmt.Printf("位与结果:%d\n", andResult) // 0001 (1)

    // 位或
    orResult := a | b
    fmt.Printf("位或结果:%d\n", orResult) // 0111 (7)

    // 位异或
    xorResult := a ^ b
    fmt.Printf("位异或结果:%d\n", xorResult) // 0110 (6)

    // 左移
    leftShiftResult := a << 1
    fmt.Printf("左移结果:%d\n", leftShiftResult) // 1010 (10)

    // 右移
    rightShiftResult := a >> 1
    fmt.Printf("右移结果:%d\n", rightShiftResult) // 0010 (2)

    // 位清空 (AND NOT)
    clearResult := a &^ b
    fmt.Printf("位清空结果:%d\n", clearResult) // 0100 (4)
}

与其他主要变成语言的差异

  • ** **&^按位置零

该操作符的使用方式是 a &^ b,它的作用是将 b 中为 1 的位在 a 中对应位置上清零。

func TestBitwiseClear(t *testing.T) {
  // 定义两个整数变量
  a := 5    // 二进制: 0101
  b := 3    // 二进制: 0011

  // 使用 &^ 按位清零
  result := a &^ b

  // 输出结果
  fmt.Printf("a &^ b 按位清零结果:%d\n", result) // 0100 (4)
}

五、循环

与其他主要变成语言的差异

GO语言仅支持循环关键字for

1. 基本的 for 循环:

  // 基本的 for 循环
  for i := 1; i <= 5; i++ {
    fmt.Println(i)
  }

2. for range 循环:

func TestFor(t *testing.T) {
  // 使用 for range 遍历数组
  numbers := []int{1, 2, 3, 4, 5}
  for index, value := range numbers {
    fmt.Printf("索引:%d,值:%d\n", index, value)
  }

  // 使用 for range 遍历字符串
  message := "Hello, Go!"
  for index, char := range message {
    fmt.Printf("索引:%d,字符:%c\n", index, char)
  }
}

3. while 条件循环:

func TestFor01(t *testing.T) {
  // 模拟 while 循环
  counter := 1
  for counter <= 5 {
    fmt.Println(counter)
    counter++
  }
}

4. 无限循环:

func TestFor02(t *testing.T) {
    // 无限循环
    counter := 0
    for {
        fmt.Println("无限循环")
        counter++

        if counter == 3 {
            break // 终止循环
        }
    }
}

5.if条件

1. 基本的 if 语句:
// 基本的 if 语句
x := 10

if x > 5 {
    fmt.Println("x 大于 5")
} else {
    fmt.Println("x 不大于 5")
}
2. if 语句的条件可以包含初始化语句:
// if 语句的条件包含初始化语句
  if x := 10; x > 5 {
    fmt.Println("x 大于 5")
  } else {
    fmt.Println("x 不大于 5")
  }
  

在这个例子中,if 语句的条件部分包含了初始化语句 x := 10,这个变量 x 只在 if 语句的作用域内有效。

3.多个 if 语句的嵌套
  // 多个 if 语句的嵌套
  x := 10

  if x > 5 {
    fmt.Println("x 大于 5")

    if x > 8 {
      fmt.Println("x 大于 8")
    }
  } else {
    fmt.Println("x 不大于 5")
  }

与其他主要变成语言的差异

  1. condition 表达式结果必须为布尔值

在 Go 语言中,条件表达式的结果必须是一个布尔值。这意味着 iffor 等语句中的条件表达式必须评估为布尔类型,不能接受非布尔类型的值

// Go 语言中的条件表达式必须是布尔值
if x > 5 {
    // ...
}

// 错误示例,编译时将会报错
if x {
    // ...
}

在上述错误示例中,x 是一个变量,但它的类型不是布尔类型,因此这个条件表达式会导致编译错误。相比之下,一些其他语言可能允许使用非布尔类型的值作为条件。

  1. 支持变量赋值

6.switch条件

与其他主要变成语言的差异

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

func TestSwitch(t *testing.T) {
  var x interface{} = "hello"

  switch x.(type) {
  case int:
    fmt.Println("x 是一个整数")
  case string:
    fmt.Println("x 是一个字符串")
  default:
    fmt.Println("未知类型")
  }

}

switch 语句的条件表达式可以是任意类型,不限制为常量或整数。这使得 switch 可以用于更复杂的条件判断,例如字符串、接口等类型。

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

func TestSwitch2(t *testing.T) {
  num := 2

  switch num {
  case 1, 2:
    fmt.Println("数字是1或2")
  case 3:
    fmt.Println("数字是3")
  default:
    fmt.Println("未知数字")
  }

}

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

func TestSwitch3(t *testing.T) {
  day := "Monday"
  switch day {
  case "Monday":
    fmt.Println("星期一")
  case "Tuesday":
    fmt.Println("星期二")
  default:
    fmt.Println("其他日子")
  }
}

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

func TestSwitch4(t *testing.T) {
  num := 2

  switch {
  case num > 5:
    fmt.Println("数字大于5")
  case num > 0:
    fmt.Println("数字大于0")
  default:
    fmt.Println("未知数字")
  }
}


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