程序设计


名称

驼峰式 ,其他与C差不多

声明

var const type func
变量 常量 类型 函数

变量

var name type = expression

name := expression

var name type

一般用 :=,如果不赋值就用第三个,如果未初始化变量,Go会自动的对应于相应类型的零值,对于复合类型的变量,零值就是所有元素或成员的零值,但是全局变量的时候不能使用短变量,必须带上var

var a ,b ,c int // int int int

var a ,b ,c = bool , int ,string // bool ,int ,string

a,b := 0 , 0.0

指针

*type 可以间接访问

有意思的一个包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package main
import (
"flag"
"fmt"
"strings"
)
// 定义标识参数n ,如果为false , “第三个中的引号”表示解释,利于我们明白
var n = flag.Bool("n", false, "omit trailing newline")
// 标识参数s 在空格处插入“第二个空格中的东西” 来分离"separator"
var sep = flag.String("s", " ", "separator") //全局变量需要用var
func main() {
// 解析命令行中的信息
flag.Parse()
// 解析命令行中的信息就可以通过args()中获得,args是参数的意思,arguments
fmt.Print(strings.Join(flag.Args(), *sep))// 连接字符串
if !*n {
fmt.Println()
}
}
-----
输出
PS F:\LearningGo> go run main.go a bc efg
a bc efgeasy
PS F:\LearningGo> go run main.go -s / a bc efg
a/bc/efgeasy
PS F:\LearningGo> go run main.go -n a bc efg
a bc efg

new 函数

new() 函数用于创建一个指定类型的零值,并返回其地址

1
2
3
4
5
6
// 用指针接受
p := new (int )
fmt.Println(*p)
--- 等价
var r int = 0
p = &r

因为最常见的变量类型都是结构体类型的,所以不推荐new

赋值

多重赋值(一次性赋值)

1
2
3
4
5
6
7
8
9
10
11
func main() {
x := 1
y := 2
x, y = y, x
fmt.Println(x, y)
}
输出 21
//牛蛙
---
var x, y = 1,2
_ , x :=func() // 作为函数的接收
  • 隐式赋值**:在隐式赋值中,赋值操作不需要显式地指定变量的类型。编程语言会根据上下文推断变量的类型。这意味着,当你将一个值赋给一个变量时,编程语言会自动确定这个值的类型,并将其赋给相应的变量。
  • 显式赋值:在显式赋值中,赋值操作需要明确指定变量的类型。在进行赋值操作时,你需要明确告诉编程语言这个变量的类型。这种方式通常出现在静态类型语言中

类型声明

type 名字 类型

type MyInt int

type YourInt int

var a MyInt , b YourInt

两者虽然底层逻辑相同,但是也不能进行比较和赋值

对外可见: 标识符大写

一个有意思的尝试

1
2
3
4
5
6
7
8
9
10
11
12
package conv
// 第一个包 实现了 华氏度和摄氏度的转换
import (
"LearningGo/tempconv"
)

func CToF(c tempconv.Celsius) tempconv.Fahrenheit {
return tempconv.Fahrenheit(c*9/5 + 32)
}
func FToC(f tempconv.Fahrenheit) tempconv.Celsius {
return tempconv.Celsius((f - 32) * 5 / 9)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package tempconv
// 第二个包定义了一些类型,一点结构,方法是传入相应摄氏度类型,重新转回string最后给你加个单位,说实话我并没看出来这个fmt.Sprintf()到底有什么用,我感觉可以直接fmt.printlf,不过它有一个好的地方就是类型转换以及返回一个值让变量接受
// %g 就是对精度格式化输出,自动选择%e,%f 进行输出
import "fmt"

type Celsius float64
type Fahrenheit float64

const (
AbsoluteZeroC Celsius = -273.5
FreeingC Celsius = 0
Boiling Celsius = 100
)
func (c Celsius) String() string {
return fmt.Sprintf("%gC", c)
}
func (f Fahrenheit) String() string {
return fmt.Sprintf("%gF", f)
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package main
// 书上的代码只有两个包,这个包还是我自己造的,用来显示输出,看看我是否是否真正理解了这个代码,然后发现第一次就错了,因为没捋清楚其中的关系。
import (
"LearningGo/conv"
"LearningGo/tempconv"
"fmt"
)

func main() {
temp := conv.CToF(tempconv.Celsius(tempconv.FreeingC))
s := temp.String()
fmt.Println(s)
}

func mae() {
var s string
fmt.Println(s, "F")
fmt.Sprintf("%sF")
}
// 翻开后面一页发现有案例,尼玛,早知道不写了
/*后面的案例实现是
a , b 通过arg[1:]读取
f:=tempconv.Fahrenheit(a) 来显式转换
比我写的可操作性更强
还要注意其中的类型转化*/

作用域

1
2
3
4
5
if f,err:= os.open(file);err!= nil{
log.Println(err)
}
f.close()
// 会显示出你f变量未定义