万字详解带你入门Go语言

Ctrl + B可查看鼠标位置Go函数源码

1.变量

变量用于描述计算机中的数据存储空间,其作用为在计算机内存中保存数据。

变量的声明格式: var 变量名称 类型;例如var age int 就声明了一个叫age的变量其类型为int。默认值为0

一次性可以声明多个变量,比如var age,num,sum int

可以讲一个变量的值,赋值给另外一个变量,并且变量中原有的旧值被新值所覆盖

1.1自动推导类型

格式:变量名 := 值

例如num := 10就是自动推导类型,具体num的类型到底是什么,那就要根据等号后面的数值,编译器自行去判断。比如这里赋值为10,那么num就是整型。

也可以进行多个变量一起赋值,比如a,b,c := 1.1,2,3

👇一个小练习:互换两个变量的值。之前我们一般引用第三个变量实现两个变量的值交换,但是go语言可以直接如下这么写

func main() {
   num1 := 10
   num2 := 20
   num1, num2 = num2, num1
   fmt.Println(num1, num2)
}

1.2变量命名规范

  • 只能由数字,字母,_(下划线)组成
  • 不能以数字开头
  • 大写字母和小写字母严格区分
  • 不能是关键字
  • 见名知意
  • 驼峰命名法:小驼峰:第一个单词首字母小写,第二个单词首字母大写;大驼峰:单词首字母全大写
  • 下划线分割法:多个单词组成的名称,全小写字母书写可以用_分隔,比如first_name

部分关键字如下
在这里插入图片描述


2.输出格式

如果我们打算输出一个变量的具体类型,可以用Printf函数,"%T" + 变量名 打印

Println和Print的区别在于加”ln“表示换行输出。

如果打算把数值对应的变量名也打印可以这么写fmt.Println("num1 = " , num1);这里面的“,”逗号相当于Java里的 “+”号

Printf:和C语言的printf函数一样,一定要指明输出一个什么类型的值。比如%d表示输出的是一个整型标量中的值。

func main() {
   num1 := 10
   num2 := 20
   num1, num2 = num2, num1
   fmt.Println(num1, num2)
   fmt.Printf("%d\n", num1) // \n表示换行输出
}

3.输入格式

Go提供了两个输入函数,Scanf()和Scan()。

Scanf()使用方法和C语言的scanf()一样,要先指明输入什么类型的值,再把想赋值的变量写进去用逗号隔开,并加上**&符号(&表示要获取这个变量的内存地址,即取地址符号**)

输入数据后敲回车键表示输入结束

func main() {
   var age int
   fmt.Println("请输入年龄")
   fmt.Scanf("%d", &age)
   fmt.Println("age = ", age)
}

我们可以用变量标记一块内存地址,并通过"&变量名"的方式打印出地址,比如fmt.Println(&age),要注意地址和变量的值无关,变量的声明只是标记了一块地址,更方便程序员去找到它。如果用Printf函数打印地址记得用"%p"

Scan()的使用比较简单,不需要说明类型,只需要在变量前加一个取地址符就行。比如fmt.Scan(&age)

总结

Scanf()语法格式:fmt.Scanf(“%_”, &num)

Scan()语法格式:fmt.Scan(&num)


4.计算机进制

进位的规则一定是:逢N进1

  1. 进制的定义:按进位的原则进行计数的方法叫做进位计数制

  2. 特点:使用一组固定的数字表示数值的大小。比如十进制是0~9这十个数,逢十进一。

  3. 进制要素:基数和位权

    • 基数:这里的N叫做基数。就是指各种进制计数制中允许选用基本数码的个数。比如10就是十进制的基数,因为逢十进一
    • 位权:215 = 2* 102 + 1*101 + 5 *100 其中102,101,100 就是位权
    • 按权相加法:让每一位上的数字字符乘以它所代表的权。
  4. 二进制:只由0和1来表示的数,计算机内部的所有运算操作都是用二进制来表示的

  5. 十六进制:一般用数字0~9和字母A到F(或a-f)表示

进制转换

二进制转换成十进制,采用按权相加法。比如二进制1011转换成十进制:1011 -> 1 * 23 + 0 * 22 + 1 * 21 + 1 * 20

十进制转二进制,采用“除2取余,逆排序”法,如下图片所示,115转换成二进制就是1110011

在这里插入图片描述


5.基础数据类型

位:最小的存储单位,计算机存储的就是二进制0,1,位就是用来存储二进制

字节:基本存储单位,用大写的B来表示,1字节 = 8位

  1. 整型(%d):分为有符号整型int,无符号整型uint

    int包括:正整数,负整数,0;

    uint包括:正整数,0

  2. 浮点类型(%f):用来表示包含小数点的数据,Go语言有float32和float64两种精度,没有double

    • float32精确到小数点后7位,float64精确到小数点后15位。

    • Go语言中涉及到关于数学运算的包中,都要求使用float64这个类型,所以建议多使用float64

    • 如果打算保留两位小数输出一个浮点型数时,可以用%.2f的格式输出,并且会四舍五入

    • 自动推导类型创建的浮点型默认为float64

  3. 布尔类型(%t):用bool关键字定义,真是true,假是false;默认值为false

  4. 字符类型(%c打印字符本身,%d打印ASC‖值):用单引号’’ 引起来的单个字符,用byte关键字定义(C语言会用char)

    • 每个字符会对应一个ASC‖值,比如’a’ = 97 ; ‘A’ = 65 ;‘0’ = 48
  5. 字符串类型(%s):用关键字string定义,并用双引号引起来

    • 注意:虽然看到的字符串变量只包含一个或一串字符,但隐藏着一个字符串的结束标志**‘\0’**,使用%s输出,只打印’\0’前面的内容

    • 测试字符串中的字符个数:用len()函数,比如fmt.Println(len(str)),str是提前定义好的string类型的变量

    • 一个汉字 = 3字符

强制类型转换

比如你支付某件商品,需要付100.5元,商家给你去个零头,付100元就行。那么100.5元是浮点型,100元是整型,这时候就要用强制类型转换。

类型转换:就是将a类型转换成b类型,如下方代码就实现将浮点型转换成整型

func main() {
   num := 3.14
   var i int = int(num)
   fmt.Println(i)
}

也可以直接fmt.Println(int(num)),输出的结果就是int类型的值:3;而且不会四舍五入。

🎈类型转换时建议将低精度类型往高精度类型转,高转低可能会丢失精度或出现数据溢出

比如:int8 -> int16 -> int32 -> int64 ; float32 -> float64


6.常量

程序运行期间不可以改变的量。常量是不可以打印地址的。

6.1常量定义使用

使用const关键字定义;格式为: const 常量名 类型 = 值

建议对常量命名时对其大写。比如const PI float64 = 3.14就定义了一个类型为float64的常量叫PI,值是3.14。

当然我们写常量时可以不写它的类型,此时常量的类型由等号后面的值确定。

6.2常量的命名规范

  • 只能由数字,字母,_(下划线)组成
  • 不能以数字开头
  • 建议全部大写,且严格区分大小写
  • 不能是关键字
  • 见名知意
  • 多个单词组成的名称,使用全大写字母书写,中间用下划线分隔

7.运算符

7.1算术运算符

运算符术语示例结果
+10 + 515
-10 - 55
*10 * 550
/10 / 52
%取余10 % 31
++自增a = 0;a++a = 1
自减a = 1;a–a = 0

注意:

  • 在Go语言中,自增自减是没有像C语言那样前自增或前自减的(就是–a这种是没有的)
  • 除法和取余运算中,除数不能为0

🎉小练习:输入半径,计算圆的周长和面积并打印出来(PI为3.14)

func main() {
   const PI = 3.14
   var r float64
   fmt.Println("请输入半径:")
   fmt.Scan(&r)
   //计算圆的周长
   p := 2 * PI * r
   fmt.Println("圆的周长为:", p)
   //计算圆的面积
   area := PI * r * r
   fmt.Println("圆的面积为:", area)
}

7.2赋值运算符

运算符说明示例
=普通赋值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

7.3关系运算符

关系运算符的结果是布尔类型的,要么是true(真),要么false(假)

运算符术语示例结果
==判断是否相等4 == 3false
!=判断是否不相等4 != 3true
<小于4 < 5true
>大于5 > 4true
<=小于等于4 <= 3false
>=大于等于3 >= 2true

7.4逻辑运算符

比如我们要判断一个人的年龄是否在18到30这个区间内,我们不能直接30 > age >18这么写,我们只能通过逻辑运算符,写成age > 18 && age < 30才行。

逻辑运算符的结果也是布尔类型。且逻辑运算符的两边一般都是关系运算或者bool类型的值。

注意和C语言的区别:在C语言中是可以把一个整型类型的变量取非的,比如int a = 2;那么!a的结果是0;但是在Go语言中这么做会报错!Go语言要求逻辑运算符旁边表达式的结果或变量是布尔类型

运算符术语示例结果
!a如果a为假,则!a为真
&&a && b如果ab都为真,结果才为真,其他都是假
||a || bab其中有一个为真,则结果为真;都为假结果才为假

7.5运算符优先级

运算符可以分为三类:

  • 特殊运算符: ()括号 ; 一个. 包名.函数名
  • 单目运算符: ! 逻辑非 ; & 取地址
  • 双目运算符:算术运算符,关系运算符,&& , || ,赋值运算符

优先级:

  1. ()括号的优先级最高

  2. 单目运算符优先级高于双目运算符

  3. 双目运算符里的优先级:算术运算符 > 关系运算符 >&& > || > 赋值运算符

7.6小练习:闰年的判定

闰年要符合下面两个条件之一

  • 年份能够被400整除
  • 年份能够被4整除但不能被100整除
func main() {
   var year int
   fmt.Scan(&year)
   b := year%400 == 0 || year%4 == 0 && year%100 != 0
   fmt.Println(b)
}

8.分支结构

8.1 if…else结构

它的用法和中文直译过来一样 如果…否则

  1. 语法格式:
if 条件判断{
   代码语句1
} else {
   代码语句2
}

注意:其他很多编程语言是要求if后的条件判断表达式要用()括号括起来,但Go语言不需要!

  1. 执行流程:程序先去看条件判断的结果是否为真,如果为真则执行if{}花括号里的代码语句1,否则执行else{}花括号里的代码语句2

练习1:判断是否成年

题目:如果年龄大于等于18,输出"已成年",否则输出"未成年"

func main() {
   age := 18
   if age >= 18 {
      fmt.Println("已成年")
   } else {
      fmt.Println("未成年")
   }
}

练习2:奇偶数判断

题目:输入一个数字,判断是否是“偶数”,如果是,输出“该数是偶数”,否则输出“该数是奇数”

func main() {
   var num int
   fmt.Scan(&num)
   if num%2 == 0 {
      fmt.Println("该数是偶数")
   } else {
      fmt.Println("该数是奇数")
   }
}

练习3:公交

题目:输入公交卡当前的余额,如果余额大于等于2元,就可以上公交车;上车后如果空座位的数量大于0,就可以坐下,否则只能站着。

func main() {
   var money float64
   fmt.Scan(&money)
   if money >= 2 {
      fmt.Println("欢迎乘车")
      var count int
      fmt.Scan(&count)
      if count > 0 {
         fmt.Println("请在空座位坐下")
      } else {
         fmt.Println("只能站着")
      }
   } else {
      fmt.Println("余额不足,请投币")
   }
}

练习3里涉及到了if语句的嵌套使用,也就是说一个if…else语句是可以嵌在另一个if…else语句里面的。

8.2 if…else if结构

  1. 基本语法如下:
if 条件判断①{
   代码段①
} else if 条件判断②{
   代码段②
} else if 条件判断③{
   代码段③
} ... {
   
} else {
   代码段n
}
  1. 执行流程:条件判断① 成立则执行 代码段①然后跳出if…else if整个结构,否则执行条件判断②,成立就执行 代码段②。以此类推。

练习:学生成绩

题目:成绩大于等于90:A等 ;成绩大于等于80且小于90:B等 ; 成绩大于等于70且小于80:C等;成绩大于等于60且小于70:D等 ;成绩小于60:E等

func main() {
   var score float64
   fmt.Scan(&score)
   if score >= 90 {
      fmt.Println("A")
   } else if score >= 80 {
      fmt.Println("B")
   } else if score >= 70{
      fmt.Println("C")
   } else if score >= 60{
      fmt.Println("D")
   } else {
      fmt.Println("E")
   }
}

8.3 switch结构

  1. 语法格式如下
switch 变量或表达式 {
case1: 代码段①
case2: 代码段②
   ...
default: 代码段n
   
}
  1. 执行流程:变量或表达式对应的值是几,就去执行相应case语句后的代码段;

需要注意的是,go语言的switch语句和C语言的不一样的点在于,go语言的不需要加break关键字来表示一个case结束。

说一些其他的点:

  • switch后面的变量或表达式可以不写
  • case后面可以不是具体的值,还可以是条件判断语句,这点很重要

练习:学生成绩

上面用if语句实现了这个案例,这次用switch语句实现

题目:成绩大于等于90:A等 ;成绩大于等于80且小于90:B等 ; 成绩大于等于70且小于80:C等;成绩大于等于60且小于70:D等 ;成绩小于60:E等

func main() {
   var score float64
   fmt.Scan(&score)
   switch  {
   case score >= 90:
      fmt.Println("A")
   case score >= 80:
      fmt.Println("B")
   case score >= 70:
      fmt.Println("C")
   case score >= 60:
      fmt.Println("D")
   default:
      fmt.Println("E")
   }
}

8.4 switch和if综合案例

题目:用户输入年份,再输入月份,输出该月的天数。(需要考虑闰年)

func main() {
   var year int
   var month int
   var day int
   fmt.Println("请输入年份")
   fmt.Scan(&year)
   fmt.Println("请输入月份")
   fmt.Scan(&month)
   //1.判断月份是否正确
   if month >= 1 && month <= 12{
      //2.如果1,3,5,7,8,10,12月,天数为31天
      switch month {
      case 1: 
         day = 31
      case 3:
         day = 31
      case 5:
         day = 31
      case 7:
         day = 31
      case 8:
         day = 31
      case 10:
         day = 31
      case 12:
         day = 31
      //3.闰年的2月有29天,否则为28天
      case 2: 
         if year % 400 == 0 || year % 4 == 0 && year % 100 != 0{
            day = 29
         } else {
            day = 28
         }
      //4.其他月份是30天
      default:
         day = 30
      }
      fmt.Println("天数是:",day)
   }  else {
      fmt.Println("输入月份错误!")
   }
}

我们会发现,上面的代码中 day = 31出现过多,我们可以优化一下,此时我们可以用fallthrough关键字。

8.5 fallthrough

fallthrough的作用在于:如果在switch语句里找到匹配的case语句去执行,发现里面的代码是fallthrough,那么程序就会接着执行下一个case语句,也可以通过此方法执行default语句。

上面的练习优化后的代码

func main() {
   var year int
   var month int
   var day int
   fmt.Println("请输入年份")
   fmt.Scan(&year)
   fmt.Println("请输入月份")
   fmt.Scan(&month)
   //1.判断月份是否正确
   if month >= 1 && month <= 12 {
      //2.如果1,3,5,7,8,10,12月,天数为31天
      switch month {
      case 1:
         fallthrough
      case 3:
         fallthrough
      case 5:
         fallthrough
      case 7:
         fallthrough
      case 8:
         fallthrough
      case 10:
         fallthrough
      case 12:
         day = 31
      //3.闰年的2月有29天,否则为28天
      case 2:
         if year%400 == 0 || year%4 == 0 && year%100 != 0 {
            day = 29
         } else {
            day = 28
         }
      //4.其他月份是30天
      default:
         day = 30
      }
      fmt.Println("天数是:", day)
   } else {
      fmt.Println("输入月份错误!")
   }
}

9.循环结构

Go语言的循环结构没那么复杂,只有一个for循环结构,没有while和do-while。

9.1 for循环基本结构

基本语法如下:

for 初始化变量 ; 判断条件 ; 修正变量 {
    代码段(循环体)
}
  • 初始化变量:对一个变量进行初始化,以记录循环次数
  • 判断条件:看条件是否成立,如果成立进入花括号{},执行循环体一次;不成立则循环结束
  • 修正变量:改变变量的值,再去执行判断条件,看是否条件是否还成立,如果符合,再去执行循环体一次

具体执行流程如下图:① -> ② -> ④ -> ③ -> ② -> ④ -> ③…直到②不成立为止

在这里插入图片描述

练习:用for循环打印0-9

func main() {
   for i := 0; i < 10; i++ {
      fmt.Println(i)
   }
}

注意这里的i只在for结构里有用,出了结构就不能再使用了

练习:求1-100数字之和

func main() {
   sum := 0
   for i := 1; i <= 100; i++ {
      sum += i
   }
   fmt.Println(sum)
}

练习:求1-100的偶数和

func main() {
   sum := 0
   for i := 1; i <= 100; i++ {
      if i%2 == 0 {
         sum += i
      }
   }
   fmt.Println(sum)
}

9.2 break语句

有时候使用循环结构时,即使条件满足,我也想强制跳出结束整个循环,这时候就要用到break关键字。

break作用:结束当前循环,后面的代码也不会再执行

比如本来我要打印0-9这些数,现在我突然改想法,打印到3(不算3这个数)就不打印了,除了可以更改条件判断语句外,我们就可以引用break关键字。具体如下:

func main() {
   for i := 0; i < 10; i++ {
      if i == 3 {
         break
      }
      fmt.Println(i)
   }
}

break常用在无法判断for要循环多少次的情况。可以看下面的案例进行理解。

案例:用户名和密码

题目:要求用户输入用户名和密码,只要不是用户名为admin,密码为888888,就一直让用户重新输入

解析:我们无法判断用户到底要输入多少次才能输入正确,这时候我们就要用到死循环和break。

死循环:就是一直循环,无法终止。只能用break跳出。就是for后面直接跟{},{}里加循环体代码

func main() {
   var userName string
   var userPwd string
   for {
      fmt.Println("请输入用户名:")
      fmt.Scan(&userName)
      fmt.Println("请输入密码:")
      fmt.Scan(&userPwd)
      //对用户名和密码进行判断
      if userName == "admin" && userPwd == "888888" {
         fmt.Println("输入正确")
         break //正确就跳出结束循环
      } else {
         fmt.Println("输入的用户名或密码错误,请重新输入")
      }
   }
}

现在我改一下题目:如果用户输入错误次数超过三次(即第三次还输入错误),就提示“输入错误信息次数太多”,并结束整个程序。

func main() {
   var userName string
   var userPwd string
   var count int //记录用户输错的次数
   for {
      fmt.Println("请输入用户名:")
      fmt.Scan(&userName)
      fmt.Println("请输入密码:")
      fmt.Scan(&userPwd)
      //对用户名和密码进行判断
      if userName == "admin" && userPwd == "888888" {
         fmt.Println("输入正确")
         break
      } else {
         count++
         if count >= 3 {
            fmt.Println("输入错误信息次数太多")
            break
         }
         fmt.Println("输入的用户名或密码错误,请重新输入")
      }
   }
}

9.3 continue语句

continue作用:结束本轮循环,然后进行循环条件的判断,如果成立则进行下一轮循环,否则退出循环。

注意continue是结束的本轮循环,会继续进行条件判断;而break是跳出结束整个循环,不会再进行条件判断。

比如我要用continue实现:输入1-5这几个数字,而3除外。

func main() {
   for i := 1; i <= 5; i++ {
      if i == 3 {
         continue
      }
      fmt.Println(i)
   }
}

9.4 循环嵌套

循环体里有循环结构就是循环嵌套

比如一个人一天吃三顿饭,每次吃饭时要说“我要吃饭”,并重复说三天。

func main() {
   for i := 0; i < 3; i++ {
      for j := 0; j < 3; j++ {
         fmt.Println("我要吃饭")
      }
   }
}

再比如我要输出一个矩形,一行有5个*,共5行。

func main() {
   for i := 0; i < 5; i++ {
      for j := 0; j < 5; j++ {
         fmt.Print("*")
      }
      fmt.Println()
   }
}

9.5 循环综合练习

练习:计算营业额

题目:2006年营业额80000元,每年增长25%,请问按此增长速度,到哪一年营业额将达到20万元?

func main() {
   year := 2006
   var money float64
   for money = 80000; money <= 200000; money *= 1.25 {
      year++
   }
   fmt.Println(year)
}

练习:水仙花数

题目:找出100-999间的水仙花数

水仙花数:是指一个三位数,他的每位数字的立方和等于其本身

func main() {
   for num := 100; num <= 999; num++ {
      a := num / 100
       b := num % 100 / 10  //或 b:= num / 10 % 10 
      c := num % 10
      if a*a*a+b*b*b+c*c*c == num {
         fmt.Println(num)
      }
   }
}

练习:乘法口诀表

func main() {
   for i := 1; i < 10; i++ {
      for j := 1; j < 10; j++ {
         fmt.Print(i, "*", j, "=", i*j, " ")
      }
      fmt.Println()
   }
}

这是矩形的,下面打印个三角形的

func main() {
   for i := 1; i < 10; i++ {
      for j := 1; j <= i; j++ {
         fmt.Print(i, "*", j, "=", i*j, " ")
      }
      fmt.Println()
   }
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Perfectkn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值