go语言一天入门(上)

举报
兔老大 发表于 2021/04/23 23:23:25 2021/04/23
【摘要】  第一个go程序 package main import "fmt" func main() { /* 这是我的第一个简单的程序 */ fmt.Println("Hello, World!")} 第一行代码 package main 定义了包名。你必须在源文件中非注释的第一行指明这个文件属于哪个包,如:package main。package main表示一个可...

 第一个go程序


  
  1. package main
  2. import "fmt"
  3. func main() {
  4. /* 这是我的第一个简单的程序 */
  5. fmt.Println("Hello, World!")
  6. }
  • 第一行代码 package main 定义了包名。你必须在源文件中非注释的第一行指明这个文件属于哪个包,如:package main。package main表示一个可独立执行的程序,每个 Go 应用程序都包含一个名为 main 的包。
  • 下一行 import "fmt" 告诉 Go 编译器这个程序需要使用 fmt 包(的函数,或其他元素),fmt 包实现了格式化 IO(输入/输出)的函数。
  • 下一行 func main() 是程序开始执行的函数。main 函数是每一个可执行程序所必须包含的,一般来说都是在启动后第一个执行的函数(如果有 init() 函数则会先执行该函数)。
  • 下一行 /*...*/ 是注释,在程序执行时将被忽略。单行注释是最常见的注释形式,你可以在任何地方使用以 // 开头的单行注释。多行注释也叫块注释,均已以 /* 开头,并以 */ 结尾,多行注释一般用于包的文档描述或注释成块的代码片段。
  • 下一行 fmt.Println(...) 可以将字符串输出到控制台,并在最后自动增加换行字符 \n。
  • 当标识符(包括常量、变量、类型、函数名、结构字段等等)以一个大写字母开头,如:Group1,那么使用这种形式的标识符的对象就可以被外部包的代码所使用(客户端程序需要先导入这个包),这被称为导出(像面向对象语言中的 public);标识符如果以小写字母开头,则对包外是不可见的,但是他们在整个包的内部是可见并且可用的(像面向对象语言中的 protected )。

数据类型

Go语言的基本类型有:

  • bool
  • string
  • int、int8、int16、int32、int64
  • uint、uint8、uint16、uint32、uint64、uintptr
  • byte // uint8 的别名
  • rune // int32 的别名 代表一个 Unicode 码
  • float32、float64
  • complex64、complex128

变量

Go语言是静态类型语言,因此变量(variable)是有明确类型的,编译器也会检查变量类型的正确性。

1)声明变量的一般形式是使用 var 关键字:var name type

Go和许多编程语言不同,它在声明变量时将变量的类型放名称后。这样做的好处就是可以避免像C语言中那样含糊不清的声明形式,例如:int* a, b; 。其中只有 a 是指针而 b 不是。如果你想要这两个变量都是指针,则需要将它们分开书写。而在 Go 中,则可以和轻松地将它们都声明为指针类型:var a, b *int

多变量声明


  
  1. var (
  2. a int
  3. b string
  4. c []float32
  5. d func() bool
  6. e struct {
  7. x int
  8. }
  9. )

 

2)除 var 关键字外,还可使用更加简短的变量定义和初始化语法。

名字 := 表达式

需要注意的是,简短模式(short variable declaration)有以下限制:

  • 定义变量,同时显式初始化。
  • 不能提供数据类型。
  • 只能用在函数内部。


和 var 形式声明语句一样,简短变量声明语句也可以用来声明和初始化一组变量:

i, j := 0, 1

3)根据值自行判定变量类型。


  
  1. package main
  2. import "fmt"
  3. func main() {
  4. var d = true
  5. fmt.Println(d)
  6. }

算术运算符


  
  1. package main
  2. import "fmt"
  3. func main() {
  4. var a int = 21
  5. var b int = 10
  6. var c int
  7. c = a + b
  8. fmt.Printf("第一行 - c 的值为 %d\n", c )
  9. c = a - b
  10. fmt.Printf("第二行 - c 的值为 %d\n", c )
  11. c = a * b
  12. fmt.Printf("第三行 - c 的值为 %d\n", c )
  13. c = a / b
  14. fmt.Printf("第四行 - c 的值为 %d\n", c )
  15. c = a % b
  16. fmt.Printf("第五行 - c 的值为 %d\n", c )
  17. a++
  18. fmt.Printf("第六行 - a 的值为 %d\n", a )
  19. a=21 // 为了方便测试,a 这里重新赋值为 21
  20. a--
  21. fmt.Printf("第七行 - a 的值为 %d\n", a )
  22. }

  
  1. 第一行 - c 的值为 31
  2. 第二行 - c 的值为 11
  3. 第三行 - c 的值为 210
  4. 第四行 - c 的值为 2
  5. 第五行 - c 的值为 1
  6. 第六行 - a 的值为 22
  7. 第七行 - a 的值为 20

位运算符

位运算符对整数在内存中的二进制位进行操作。

下表列出了位运算符 &, |, 和 ^ 的计算:

 

p q p & q p | q p ^ q
0 0 0 0 0
0 1 0 1 1
1 1 1 1 0
1 0 0 1 1

 

假定 A = 60; B = 13; 其二进制数转换为:

A = 0011 1100

B = 0000 1101

-----------------

A&B = 0000 1100

A|B = 0011 1101

A^B = 0011 0001

 

运算符 描述 实例
& 参与运算的两数各对应的二进位相与。 (A & B) 结果为 12, 二进制为 0000 1100
| 参与运算的两数各对应的二进位相或 (A | B) 结果为 61, 二进制为 0011 1101
^ 参与运算的两数各对应的二进位相异或,当两对应的位相异时,结果为1。 (A ^ B) 结果为 49, 二进制为 0011 0001
<< 左移n位就是乘以2的n次方。 其功能把"<<"左边的运算数的各二进位全部左移若干位,由"<<"右边的数指定移动的位数,高位丢弃,低位补0。 A << 2 结果为 240 ,二进制为 1111 0000

 赋值运算符

下表列出了所有Go语言的赋值运算符。

运算符 描述 实例
= 简单的赋值运算符,将一个表达式的值赋给一个左值 C = A + B 将 A + B 表达式结果赋值给 C
+= 相加后再赋值 C += A 等于 C = C + A
-= 相减后再赋值 C -= A 等于 C = C - A
*= 相乘后再赋值 C *= A 等于 C = C * A
/= 相除后再赋值 C /= A 等于 C = C / A
%= 求余后再赋值 C %= A 等于 C = C % A
<<= 左移后赋值 C <<= 2 等于 C = C << 2
>>= 右移后赋值 C >>= 2 等于 C = C >> 2
&= 按位与后赋值 C &= 2 等于 C = C & 2
^= 按位异或后赋值 C ^= 2 等于 C = C ^ 2
|= 按位或后赋值 C |= 2 等于 C = C | 2

 

其他运算符

 

运算符 描述 实例
& 返回变量存储地址 &a; 将给出变量的实际地址。
* 指针变量。 *a; 是一个指针变量

以下实例演示了其他运算符的用法:

实例


  
  1. package main
  2. import "fmt"
  3. func main() {
  4. var a int = 4
  5. var b int32
  6. var c float32
  7. var ptr *int
  8. /* 运算符实例 */
  9. fmt.Printf("第 1 行 - a 变量类型为 = %T\n", a );
  10. fmt.Printf("第 2 行 - b 变量类型为 = %T\n", b );
  11. fmt.Printf("第 3 行 - c 变量类型为 = %T\n", c );
  12. /* & 和 * 运算符实例 */
  13. ptr = &a /* 'ptr' 包含了 'a' 变量的地址 */
  14. fmt.Printf("a 的值为 %d\n", a);
  15. fmt.Printf("*ptr 为 %d\n", *ptr);
  16. }

以上实例运行结果:

第 1 行 - a 变量类型为 = int
第 2 行 - b 变量类型为 = int32
第 3 行 - c 变量类型为 = float32
a 的值为  4
*ptr 为 4

运算符优先级

由上至下代表优先级由高到低:

优先级 运算符
5 * / % << >> & &^
4 + - | ^
3 == != < <= > >=
2 &&
1 ||

循环

普通for循环


  
  1. package main
  2. import "fmt"
  3. func main() {
  4. sum := 0
  5. for i := 0; i <= 10; i++ {
  6. sum += i
  7. }
  8. fmt.Println(sum)
  9. }

 foreach

这种格式的循环可以对字符串、数组、切片等进行迭代输出元素。


  
  1. package main
  2. import "fmt"
  3. func main() {
  4. strings := []string{"google", "runoob"}
  5. for i, s := range strings {
  6. fmt.Println(i, s)
  7. }
  8. numbers := [6]int{1, 2, 3, 5}
  9. for i,x:= range numbers {
  10. fmt.Printf("第 %d 位 x 的值 = %d\n", i,x)
  11. }
  12. }

 

函数


  
  1. func function_name( [parameter list] ) [return_types] {
  2. 函数体
  3. }
  • func:函数由 func 开始声明
  • function_name:函数名称,函数名和参数列表一起构成了函数签名。
  • parameter list:参数列表,参数就像一个占位符,当函数被调用时,你可以将值传递给参数,这个值被称为实际参数。参数列表指定的是参数类型、顺序、及参数个数。参数是可选的,也就是说函数也可以不包含参数。
  • return_types:返回类型,函数返回一列值。return_types 是该列值的数据类型。有些功能不需要返回值,这种情况下 return_types 不是必须的。
  • 函数体:函数定义的代码集合。

  
  1. /* 函数返回两个数的最大值 */
  2. func max(num1, num2 int) int {
  3. /* 声明局部变量 */
  4. var result int
  5. if (num1 > num2) {
  6. result = num1
  7. } else {
  8. result = num2
  9. }
  10. return result
  11. }

返回多个值


  
  1. package main
  2. import "fmt"
  3. func swap(x, y string) (string, string) {
  4. return y, x
  5. }
  6. func main() {
  7. a, b := swap("Google", "Runoob")
  8. fmt.Println(a, b)
  9. }

引用传参


  
  1. package main
  2. import "fmt"
  3. func main() {
  4. /* 定义局部变量 */
  5. var a int = 100
  6. var b int= 200
  7. fmt.Printf("交换前,a 的值 : %d\n", a )
  8. fmt.Printf("交换前,b 的值 : %d\n", b )
  9. /* 调用 swap() 函数
  10. * &a 指向 a 指针,a 变量的地址
  11. * &b 指向 b 指针,b 变量的地址
  12. */
  13. swap(&a, &b)
  14. fmt.Printf("交换后,a 的值 : %d\n", a )
  15. fmt.Printf("交换后,b 的值 : %d\n", b )
  16. }
  17. func swap(x *int, y *int) {
  18. var temp int
  19. temp = *x /* 保存 x 地址上的值 */
  20. *x = *y /* 将 y 值赋给 x */
  21. *y = temp /* 将 temp 值赋给 y */
  22. }

数组

声明:

语法格式如下:

var variable_name [SIZE] variable_type

以上为一维数组的定义方式。例如以下定义了数组 balance 长度为 10 类型为 float32:

var balance [10] float32

初始化:

var balance = [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}

初始化数组中 {} 中的元素个数不能大于 [] 中的数字。

如果忽略 [] 中的数字不设置数组大小,Go 语言会根据元素的个数来设置数组的大小:

 var balance = [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}

该实例与上面的实例是一样的,虽然没有设置数组的大小。

 balance[4] = 50.0

初始化二维数组:


  
  1. a = [3][4]int{
  2. {0, 1, 2, 3} , /* 第一行索引为 0 */
  3. {4, 5, 6, 7} , /* 第二行索引为 1 */
  4. {8, 9, 10, 11}, /* 第三行索引为 2 */
  5. }

注意:以上代码中倒数第二行的 } 必须要有逗号,因为最后一行的 } 不能单独一行,也可以写成这样:


  
  1. a = [3][4]int{
  2. {0, 1, 2, 3} , /* 第一行索引为 0 */
  3. {4, 5, 6, 7} , /* 第二行索引为 1 */
  4. {8, 9, 10, 11}} /* 第三行索引为 2 */

指针

和c一样


  
  1. package main
  2. import "fmt"
  3. func main() {
  4. var a int= 20 /* 声明实际变量 */
  5. var ip *int /* 声明指针变量 */
  6. ip = &a /* 指针变量的存储地址 */
  7. fmt.Printf("a 变量的地址是: %x\n", &a )
  8. /* 指针变量的存储地址 */
  9. fmt.Printf("ip 变量储存的指针地址: %x\n", ip )
  10. /* 使用指针访问值 */
  11. fmt.Printf("*ip 变量的值: %d\n", *ip )
  12. }

  
  1. a 变量的地址是: 20818a220
  2. ip 变量储存的指针地址: 20818a220
  3. *ip 变量的值: 20

空指针判断:

if(ptr != nil) /* ptr 不是空指针 */
if(ptr == nil) /* ptr 是空指针 */

多重指针: 


  
  1. package main
  2. import "fmt"
  3. func main() {
  4. var a int
  5. var ptr *int
  6. var pptr **int
  7. a = 3000
  8. /* 指针 ptr 地址 */
  9. ptr = &a
  10. /* 指向指针 ptr 地址 */
  11. pptr = &ptr
  12. /* 获取 pptr 的值 */
  13. fmt.Printf("变量 a = %d\n", a )
  14. fmt.Printf("指针变量 *ptr = %d\n", *ptr )
  15. fmt.Printf("指向指针的指针变量 **pptr = %d\n", **pptr)
  16. }

  
  1. 变量 a = 3000
  2. 指针变量 *ptr = 3000
  3. 指向指针的指针变量 **pptr = 3000

 

 

文章来源: fantianzuo.blog.csdn.net,作者:兔老大RabbitMQ,版权归原作者所有,如需转载,请联系作者。

原文链接:fantianzuo.blog.csdn.net/article/details/106193520

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。