Go语言学习 _基础001

Go语言学习 _基础001

HelloWorld
package main // main 函数必须处于 main 包中 不管是在什么路径下 反正就是要有main包

import (  // 引入 包 对多个包的 引入可以这样简写 
	"fmt" // 对于单个包 : import "fmt"  即可
	"os"
)

func main() {

	fmt.Println("Hello World" )
	fmt.Println(os.Args)
	if len(os.Args) > 1 {
		fmt.Println("Hello World" , os.Args[1]) // 输出 main函数参数 在 参数数组长度大于 1 时
	}
    //return 1  不能在 main() 里面直接返回参数 编译无法通过
   os.Exit(-1)  // 可以通过这样的 方式 带出 参数
}
测试相关

测试的程序 一定要写在 xxx_test 文件下 测试的 function 一定要是 TestXxxx 至于其他成分 之后在再进行解释,示例如下

package fib_test

import (
   "fmt"
   "testing"
)

func TestFibList(t *testing.T) { // 实现一个 简单的 斐波那契数列输出
   var a int = 1
   var b int = 1
   fmt.Print(a)
   for i := 0; i < 5; i++ {
      fmt.Print(" ", b)
      tmp := a
      a = b
      b = tmp + a
   }
   fmt.Println()
}

func TestExchange(t *testing.T) {
   a := 1
   b := 2
   t.Log(a, b)
   a, b = b, a // 像是 python go 也支持这样简写的 变量交换
   t.Log(a, b)
}
常量相关:

iota只能被使用在const限定中,相当于一个常量的计数器 或者说是 迭代操作的关键字

iota相当于一个枚举值,默认从0开始,在一个const中,会进行+1,或者其他类型的操作

iota不会因为const中被赋值了固定值,就不再增加,const中每有一个常量就+1,如下一周七天的例子

每次进入一个新的const,iota都会重新开始计算

像下面的 可读、可写、可执行 这三个权限 常量的 都是 对 1 的 左移操作,常数每多定义一个 就会 带上上一个的值和操作 重新运算 得出新的 参数值。

package constant_test

import "testing"

const (
   Monday = iota + 1 // 对于连续常量采用的 简洁写法
   Tuseday
   Wednesday
   Thu
   Fir
   Sat
   Sun
)

const (
   Readable = 1 << iota
   Writeable
   Executable
)

func TestConstant(t *testing.T) {
   t.Log(Monday, Tuseday)
}

func TestXable(t *testing.T) {
   //t.Log()
   a := 7 // 0111
   t.Log(a&Readable == Readable, a&Writeable == Writeable, a&Executable == Executable)
}
变量的定义:

go 中 有变量推断器 我们可以严格的按照类型声明变量(如果需要先声明在进行初始化),也可以直接采用简略的 方式 对变量进行声明和初始化

package type_test

import (
   "fmt"
   "testing"
)

type MyInt int64

func TestImplicit(t *testing.T) { // go 不支持任何形式的 默认 的 类型转换 有需转换 必须声明
   var a int32 = 1
   var b int64 // Go语言中 有 int64 和 int32 两个 整形类别 , 是可以直接声明 int 的 但是 int 的 长度就 与 OS 字长 直接相关 为减少 不确定因素 建议 在定义变量时 做显式的 声明
   b = int64(a)
   var c MyInt
   //c = b 严格的限制 让 哪怕是 同类型的 别名都不能 自动转换 
   c = MyInt(b) 
   t.Log(a, b, c)
}

func TestPoint(t *testing.T) {
   a := 1 // 采用简略的 方式 对变量进行声明和初始化 
   aPtr := &a // 获取指针 
   //aPtr = aPtr + 1 // invalid operation: aPtr + 1 (mismatched types *int and int) TODO 不支持指针运算,避免越界
   t.Log(a, aPtr)
   //t.Log("%T %T", a, aPtr) // Log call has possible formatting directive %T
   fmt.Printf("%T %T", a, aPtr)
}

func TestString(t *testing.T) {
   var s string // 字符串 在 go 中 是一种 基本类型 // 其实质就和 类型的 名字一样 是一个个 字符串接起来的 
    // go 中 没有 专门的 char 类型 所有 字符 都是 通过 整形 来 存储的 不过 只是根据 需要 使用 长度 不同的 整形 byte、int32、int64、uint8、uint16、uint32、uint64 都是可以的
   t.Log("*" + s + "*")
   t.Log(len(s))
   //if s == nil { TODO string 默认初始化为 "" 所以不需要这个对空值的判断
   if s == "" {

   }
}
运算符:

没有前置 ++ 、-- 只支持后置,这也是go语言坚持的 只用一种方式 解决一类问题的理念。

‘==’ :可以使用 == 来比较数组

  • 相同维数且每个元素都一致的两个数组 可以判等
package opt_test

import "testing"

const (
    Readable   = 1 << iota // 0001
    Writeable              // 0010
    Executable             // 0100
)

func TestCompareArray(t *testing.T) {
    a := [...]int{1, 2, 3, 4}
    b := [...]int{1, 3, 4, 5}
    // c := [...]int{1, 2, 3, 4, 5}
    d := [...]int{1, 2, 3, 4}
    t.Log(a == b)
    //t.Log(b == c) 维度不同 编译都无法通过
    t.Log(d == a)
}
func TestBitClear(t *testing.T) {
    //t.Log()
    a := 7 // 0111
    // &^ 按位清零
    a = a &^ Readable
    a = a &^ Executable
    t.Log(a&Readable == Readable, a&Writeable == Writeable, a&Executable == Executable)
   // === RUN   TestBitClear
   // opt_test.go:27: false true false
   // --- PASS: TestBitClear (0.00s)
   // PASS
}
原文地址:https://www.cnblogs.com/OwlInTheOaktree/p/15203310.html