Go基础语法

流程控制

一共有三种:顺序结构,选择结构,循环结构

if语句

/*
if与else if的区别:
	1:if无论是否满足条件都会向下执行,直到程序结束,else if 满足一个条件就会停止执行。
	2:由于if都会执行一遍,则可能会同一个需要判断的事件,会进入2个if语句中,出现错误,而else if就不会发生这样的事情。
 */
func main() {
	var a int = 15
	var score int = 80
	if a > 20 {
		fmt.Println("a大于20")
	}
	if a > 10 {
		fmt.Println("a大于10")
	}

	if score >= 90 && score <= 100 {
		fmt.Println("A")
	} else if score >= 80 && score < 90 {
		fmt.Println("B")
	} else if score >= 70 && score < 80 {
		fmt.Println("C")
	} else if score >= 60 && score < 70 {
		fmt.Println("D")
	} else {
		fmt.Println("F")
	}
}

if嵌套

// 通过if嵌套实现二次验证密码
func main() {
   var a, b int
   var pwd int = 20221108

   fmt.Print("请输入密码:")
   fmt.Scan(&a)
   if a == pwd {
      fmt.Print("请再次输入密码:")
      fmt.Scan(&b)
      if b == pwd {
         fmt.Println("登录成功")
      } else {
         fmt.Println("登录失败,密码输入不一致")
      }
   } else {
      fmt.Println("密码错误")
   }
}

switch语句

// switch语句
func main() {
	var score int = 90

	//case来匹配 switch后的结果
	switch score {
	case 90:
		fmt.Print("A")
		fallthrough //通过此关键字实现穿透
	case 80:
		fmt.Print("B")
		//由于每一个case自带break效果 只能穿透到这里 如果继续穿透 需要再添加fallthrough
		fallthrough
	case 70, 60, 50:
		//如果想过提前结束可以添加break
		if score == 80 {
			break
		}
		fmt.Print("C")
	default:
		fmt.Print("D")
	}

	//switch的默认条件是 bool=ture
	switch {
	case false:
		fmt.Print("false")
	case true:
		fmt.Print("true")
	default:
		fmt.Println("其他")
	}
}

与java不同case后默认自带break效果 所以一般不存在穿透效果

所以需要使用fallthrough关键字来实现穿透效果

单独使用fallthrough会强制穿透,不管下一个case中的条件是否满足所以可以搭配break使用

for循环

func main() {
   //循环10次
   for i := 0; i < 10; i++ { //i的作用域只在for循环中哦
      fmt.Println(i)
   }

   //计算从1到10的和
   sum := 0
   for i := 1; i <= 10; i++ {
      sum += i
   }
   fmt.Println(sum)

   j := 0
   for j < 110 {
      fmt.Println(j)
      j++
   }
   
  

}

for循环中的所有参数都可以省略有这么几种情况:
1、for :循环条件: 这样需要声明变量起始值 并在循环体中控制 变量的增减
2、for {} 这就是无限循环

练习

func main() {
   //打印一个 5*5的星号方阵
   fmt.Println("5*5的星号方阵哦")
   for i := 1; i <= 5; i++ {
      for i := 1; i <= 5; i++ {
         fmt.Print("  *")
      }
      fmt.Println()
   }

   //打印九九乘法表
   fmt.Println("九九乘法表")
   for i := 1; i <= 9; i++ {
      for j := 1; j <= i; j++ {
         fmt.Printf("%d*%d=%d/t", j, i, i*j)
      }
      fmt.Println()
   }
    //这样也是可行的  不过效率就降低了
    for i := 1; i <= 9; i++ {
      for j := 1; j <= 9; j++ {
          if j > i {
              break
          }
         fmt.Printf("%d*%d=%d/t", j, i, i*j)
      }
      fmt.Println()
   }
    
}

break 与 continue

func main() {

   //break是直接结束本循环程序
   for i := 0; i < 10; i++ {
      if i == 5 {
         break
      }
      fmt.Println(i)
   }

   //continue跳过本次循环
   for i := 0; i < 10; i++ {
      if i == 5 {
         continue
      }
      fmt.Println(i)
   }
}

string

func main() {
   str := "hello,my country"
   fmt.Println(str)

   //获取字符串的长度
   fmt.Println("字符串的长度为:", len(str))

   //获取字符串指定的字节
   fmt.Println("字节打印:", str[2]) //acsii编码值108
   fmt.Printf("%c\n", str[2])

   //for循环遍历字符串
   for i := 0; i < len(str); i++ {
      fmt.Printf("%c", str[i])
   }

   for i, j := range str {//i 是字符串下标 j是字节
      fmt.Print(i)
      fmt.Printf("%c", j)
   }
}

string中的字节不能被单独改变

函数

函数是基本的代码块 用于执行一个任务

func 函数名 (参数1,参数2,...)返回值类型 int,int,...{
	函数体
	return 返回结果
}
  • 无参无返回值、几个或没有参及返回值
func main() {

   fmt.Println(add(2, 3))
   printinfo()
   printinfo2("你好")
   a, b := printinfo3("世界", "你好")
   fmt.Println(a, b)

}

func printinfo() {
   fmt.Println("我是无参无返回值")
}

func printinfo2(str string) {
   fmt.Println("我是有参无返回值", str)
}

func printinfo3(str, st2 string) (string, string) {
   return st2, str
}

func add(a, b int) int {
   c := a + b
   return c
}

可变参数

func main() {
   getSum(2, 56, 23, 12, 4, 2)

}

// 可变参数
func getSum(nums ...int) { //意为可变参数其实是一个数组?
   sum := 0
   for i := 0; i < len(nums); i++ {
      sum += nums[i]

   }
   fmt.Println(sum)
}
  • 这里可以看到 可变参数是如何定义的 变量名…数据类型
  • 其次通过调用函数,发现可变参数可以一直输入变量,所以可变参数要定义再最后
  • 而且同java 可变参数有且只有一个

值传递、引用传递

值传递 对象有基本类型 int string bool float array

/*
   值传递 将arr中的值复制一份到arr2上 即开辟了两个空间
   所以修改arr2中的元素并不会影响arr
   使用值传递的数据有 基础类型,array,struct
*/
func main() {
   //值传递
   arr := [4]int{1, 2, 3, 4}
   update(arr)
   fmt.Println(arr)
   fmt.Println("========================")

   str := "世界"
   updateString(str)
   fmt.Println(str)

   //引用地址传递
}

func update(arr2 [4]int) {
   fmt.Println(arr2)
   arr2[0] = 100
   fmt.Println(arr2)
}

func updateString(str string) {
   fmt.Println(str)
   str = "你好"
   fmt.Println(str)
}

引用类型 对象有 slice map chan…

/*
	s1 与s2指向的空间是同一个 s2修改了一个值 
	s1也会随之变化
*/

func main() {
   //切片 其实就是可以扩容的数组
   s1 := []int{1, 2, 3, 4}
   update2(s1)
   fmt.Println(s1)

}

func update2(s2 []int) {
   fmt.Println("传递的数据:", s2)
   s2[0] = 100
   fmt.Println("更新后:", s2)
}

变量作用域

  • 在函数中定义的变量叫做局部变量
  • 在函数外定义的变量叫做全局变量
// 定义全局变量
var num int = 100

func main() {
   temp := 199

   if b := 1; b < 10 {
      temp := 99
      num := 00
      fmt.Println(temp) //遵循就近原则 99
      fmt.Println(b)
      fmt.Println(num) //0
   }
   fmt.Println(temp) // 199
   //fmt.Println(b)  b只能在if中使用

   fmt.Println(num)
}

func f1() {
   num := 11
   a := 1
   fmt.Println(a)
   fmt.Println(num) //11
}

func f2() {
   //fmt.Println(a)   不能使用其他函数中定义的变量
   fmt.Println(num) //100
}
  • 一定要注意变量的作用域

defer 延迟执行

  • defer的作用同队列一样 先入后出
  • 当然并不意味着defer标识的函数会最后传入参数执行,程序还是顺序传入参数 然后最后执行
func main() {
   a := 10
   fmt.Println(a) //10
   //参数 10传递进去了,不过被延迟到最后执行
   defer f(a)     // 10
   a++
   fmt.Println("我在defer后", a) // 11
}

func f(s int) {
   fmt.Println(s)
}

函数的理解

函数本身也是数据类型,所以函数也是变量,可以复制

func main() {
   fmt.Println(f1)        //f1在不加()下使用就是一个变量
   fmt.Printf("%T\n", f1) //类型是func(int, int)   定义的函数是什么样的 类型就是什么样的
   //定义一个函数类型变量
   var f2 func(int, int) = f1
   f2(2, 3)               //输出 为 2 3 证明 f1 的值赋予了f2
   fmt.Printf("%T\n", f2) //func(int, int)
   fmt.Println(f2)        //地址与f1一致 指向同一个空间 0x69fe60

}

func f1(a, b int) {
   fmt.Println(a, b)
}

匿名函数 go是可以函数式编程的

func main() {
   ff1()      //调用f1函数
   ff2 := ff1 //将f1变量的值赋予f2
   ff2()

   //匿名函数
   func() {
      fmt.Println("我是匿名函数")
   }() //匿名函数自己调用自动

   //匿名函数同普通函数一样可以添加参数、返回值
   x := func(a, b int) int {
      fmt.Println("我是匿名函数", a, b)
      return a + b
   }(1, 2)

   fmt.Println(x)

}

func ff1() {
   fmt.Println("f1")
}

回调函数

  • 高阶函数 接受一个函数作为参数的函数
  • 回调函数 作为一个参数的函数
func main() {
   //r := sum(1, 2)
   //fmt.Println(r)
   r1 := opear(1, 2, sum)
   fmt.Println(r1)

   r2 := opear(3, 6, mul)
   fmt.Println(r2)

   r3 := opear(4, 7, func(a int, b int) int {
      return a * b
   })
   fmt.Println(r3)

   r4 := opear(8, 4, func(a int, b int) int {
      if b == 0 {
         return 0
      }
      return a / b
      
   })
   fmt.Println(r4)

}

func sum(a, b int) int {
   return a + b
}

func mul(a int, b int) int {
   return a - b
}

func opear(a, b int, fun func(int, int) int) int {
   r := fun(a, b)
   return r
}

闭包

函数调用函数就会生成一个结构:闭包

一个外层函数,内有一个内层函数,内层函数会操作外层函数的局部变量

并且这个外层函数的返回值就是这个内存函数 这就是闭包结构

*一般来说当函数调用完毕 函数中的变量等应该会被销毁,但是闭包结构中的外层函数的局部变量不会随着外层函数的结束而销毁,因为内层函数还在继续使用

func main() {
   r1 := inc()
   fmt.Println(r1)

   v1 := r1()        //1
   fmt.Println(v1)   //1
   v2 := r1()        //2
   fmt.Println(v2)   //2
   fmt.Println(r1()) //3
   fmt.Println(r1()) //4
   fmt.Println(r1()) //5

   //i重新计数
   r2 := inc()
   fmt.Println(r2)
   v3 := r2()        //1
   fmt.Println(v3)   //1
   fmt.Println(r1()) //6
   fmt.Println(r2()) //2

}

func inc() func() int { //外层函数
   //局部变量
   i := 0
   //定义一个匿名函数,给变量自增并返回
   fun := func() int { //内层函数
      i++ //操作外层函数局部变量
      return i
   }
   return fun
}

原文地址:http://www.cnblogs.com/onlyxue/p/16870473.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性