Go学习
原由
Go语言出来了好长时间.但是一直没有去学习.本来想着在Java深耕来着.但,实在跟不上JDK的更新速度.
只能去学习下别的语言看看.
顺便看看别的语言世界是怎么样的.
1. 语法
首先是变量的类型.跟Java差不多.但是由于Go和C,C++类似,所以还是有一些衍生变量的.
也就是一些在基础数据类型上扩展而来的复合数据类型(个人理解,勿喷)
比如:
(a) 指针类型(Pointer)(b) 数组类型 (c) 结构化类型(struct) (d) Channel 类型
(e) 函数类型 (f) 切片类型 (g) 接口类型(interface) (h) Map 类型
变量声明
声明一个变量是老三样了.无非就是类型推断.但其中还是有点需要记得.
变量重新声明(个人理解)
var intVal int
intVal :=1 // 这时候会产生编译错误
但是:
var intVAl int
intVal, intVal2 := 2,3
这种就是正确的.这种声明方式只能够在函数体内使用. 所以.记住这点与Java不同的就好. 还有就是 多变量声明:
package main
var x, y int
var ( // 这种因式分解关键字的写法一般用于声明全局变量
a int
b bool
)
var c, d int = 1, 2
var e, f = 123, "hello"
//这种不带声明格式的只能在函数体中出现
//g, h := 123, "hello"
func main(){
g, h := 123, "hello"
println(x, y, a, b, c, d, e, f, g, h)
}
类型
略
值类型
略
引用类型
略
这俩点没有直接书写或者记录.原因是自己记住了的.
因为入门就是自学的C,指针这块当初也学了.虽然现在忘记的差不多了.
但还是能够理解意思.不多表述
小技巧
交换俩个变量的值:
var val1 ,val2 = 2,3;
val1,val2 = val2,val1
弃用变量值:空白标识符:_
package main
import "fmt"
func main() {
_,numb,strs := numbers() //只获取函数返回值的后两个
fmt.Println(numb,strs)
}
//一个可以返回多个值的函数
func numbers()(int,int,string){
a , b , c := 1 , 2 , "str"
return a,b,c
}
常量
const:不可改变的量
值不变得变量,成为常量.
在Java中可以使用final 保持一个变量的值不改变,不可改变.
在Go中,使用 **const** 关键字来保持不变.
并且只能是布尔型、数字型(整数型、浮点型和复数)和字符串型这些数据类型定义为常量.
其他的均不可以.
使用:
import "unsafe"
const (
a = "abc"
b = len(a)
c = unsafe.Sizeof(a)
)
func main(){
println(a, b, c)
}
---------------------------------------------------------------------------
import "fmt"
func main() {
const LENGTH int = 10
const WIDTH int = 5
var area int
const a, b, c = 1, false, "str" //多重赋值
area = LENGTH * WIDTH
fmt.Printf("面积为 : %d", area)
println()
println(a, b, c)
}
iota:可被修改的量
配合 const 一起使用.在 const 出现时,重置为0;每新增一行,常量 iota 的值 +1
例如:
const (
a = iota
b = iota
c = iota
)
const (
a = iota
b
c
)
这俩者相等.第一个iota=0;
上面的表达式可以这么说:
const(
a = 0
b = iota + 1
c = iota + 1
)
这里的iota并不是定义一个可修改的常量.而是iota本身是一个自增的量.起始值 = 0.下次再次使用自增 +1.
被打断iota
iota的值是可被打断的.
即: 一连串使用iota值得变量.中间被赋予别的值了.那么是这样的现象:
package main
import "fmt"
func main() {
const (
a = iota //0
b //1
c //2
d = "ha" //独立值,iota += 1
e //"ha" iota += 1
f = 100 //iota +=1
g //100 iota +=1
h = iota //7,恢复计数
i //8
)
fmt.Println(a,b,c,d,e,f,g,h,i)
}
以上实例运行结果为:
0 1 2 ha ha 100 100 7 8
2.运算符
运算符之所以单独拿起来讲.是因为上面的内容是一块.够多了的.
不好再归为一类去讲.
分类:
算术运算符
关系运算符
逻辑运算符
位运算符
赋值运算符
其他运算符
其中需要记住的是
位运算符: ^, |, &, << , >>
指针相关操作 *(指针运算符), &(对变量地址的引用)
就这么几种.但是在C中还有 无符号右移.而这点GO语言中没有.
最后在记住运算符优先级别即可:
优先级 运算符
5 * / % << >> & &^
4 + - | ^
3 == != < <= > >=
2 &&
1 ||
3. 条件语句
Go不支持while,do...while等语句. 条件语句支持:
if if...else if嵌套语句
switch 语句 select 语句
IF详解:
if 布尔表达式 { 函数体(个人叫法) }
if 布尔表达式 { 函数体(个人叫法) } else{ 函数体(个人叫法) }
if 嵌套:略,,,,,,懒得写了
if 好的地方也只有不用在 布尔表达式 外围 围上括号了.算是简化版本了吧
switch 详解
switch var1 {
case val1:
...
case val2:
...
default:
...
}
在Go的switch中,每个case不用书写 break 跳出动作.
如果我们匹配了case1,还需要执行case2的话,可以使用 fallthrough 进行书写.
switch实例
package main
import "fmt"
func main() {
/* 定义局部变量 */
var grade string = "B"
var marks int = 90
switch marks {
case 90: grade = "A"
case 80: grade = "B"
case 50,60,70 : grade = "C"
default: grade = "D"
}
switch {
case grade == "A" :
fmt.Printf("优秀!\n" )
case grade == "B", grade == "C" :
fmt.Printf("良好\n" )
case grade == "D" :
fmt.Printf("及格\n" )
case grade == "F":
fmt.Printf("不及格\n" )
default:
fmt.Printf("差\n" );
}
fmt.Printf("你的等级是 %s\n", grade );
}
我们可以在每个case后面书写多个值.
Type-switch
switch 语句
还可以用于 type-switch 来判断某个 interface 变量中实际存储的变量类型。
实例
switch x.(type){
case type:
statement(s);
case type:
statement(s);
/* 你可以定义任意个数的case */
default: /* 可选 */
statement(s);
}
func main() {
var x interface{}
switch i := x.(type) {
case nil:
fmt.Printf(" x 的类型 :%T",i)
case int:
fmt.Printf("x 是 int 型")
case float64:
fmt.Printf("x 是 float64 型")
case func(int) float64:
fmt.Printf("x 是 func(int) 型")
case bool, string:
fmt.Printf("x 是 bool 或 string 型" )
default:
fmt.Printf("未知型")
}
x 的类型 :<nil> 这里面的nil类型暂时还没讲到.所以知道有这么个类型就可以了
fallthrough
上面有讲到,如果执行力一条case还不满意怎么办. 那么可以使用fallthrough执行另一条case;
func main() {
switch {
case false:
fmt.Println("1、case 条件语句为 false")
fallthrough
case true:
fmt.Println("2、case 条件语句为 true")
fallthrough
case false:
fmt.Println("3、case 条件语句为 false")
fallthrough
case true:
fmt.Println("4、case 条件语句为 true")
case false:
fmt.Println("5、case 条件语句为 false")
fallthrough
default:
fmt.Println("6、默认 case")
}
以上代码执行结果为:
2、case 条件语句为 true
3、case 条件语句为 false
4、case 条件语句为 true
那么,这个fallthrough 可以终止吗??不想执行另一条了
switch{
case 1:
...
if(...){
break
}
fallthrough
// 此时switch(1)会执行case1和case2,
// 但是如果满足if条件,则只执行case1
case 2:
...
case 3:
}
这么写就可以啦!!
select 语句
说道这个select语句想到了什么呢? 反正我是想到了 MySql 的 select * from xxx
语法
https://www.runoob.com/go/go-select-statement.html
select 涉及到了:
每个 case 都必须是一个通信
所有 channel 表达式都会被求值
所有被发送的表达式都会被求值
如果任意某个通信可以进行,它就执行,其他被忽略。
如果有多个 case 都可以运行,Select 会随机公平地选出一个执行。其他不会执行。
否则:
如果有 default 子句,则执行该语句。
如果没有 default 子句,select 将阻塞,直到某个通信可以运行;Go 不会重新对 channel 或值进行求值。
所以这里就不多描述了.等博主整个基础再来补充,填上自己的理解哈
循环语句
GO的for循环有三种形式;只有一种会使用到 分号. 其他情况下,分号都是被省略的.
和C的for一样
for init; condition; post { }
和C的while一样
for condition { }
和C的for(;;)一样
for { }
讲解
init: 赋值表达式.给控制变量赋予初始值
condition: 关系表达式或逻辑表达式,循环控制条件;
post:一般为赋值表达式,给控制变量增量或减量。
实例
func main() {
sum := 0
for i := 0; i <= 10; i++ {
sum += i
}
fmt.Println(sum)
}
func main() {
sum := 1
for ; sum <= 10; {
sum += sum
}
fmt.Println(sum)
// 这样写也可以,更像 While 语句形式
for sum <= 10{
sum += sum
}
fmt.Println(sum)
}
func main() {
sum := 0
for {
sum++ // 无限循环下去
}
fmt.Println(sum) // 无法输出
}
For-each range 循环
这种循环可以看做Java中的 for in 循环;
func main() {
strings := []string{"google", "runoob"}
for i, s := range strings {
fmt.Println(i, s)
}
numbers := [6]int{1, 2, 3, 5}
for i,x:= range numbers {
fmt.Printf("第 %d 位 x 的值 = %d\n", i,x)
}
}
上面的for-each 涉及到了数组这里还没讲到.看看就OK
跳出循环 使用一些关键字,可以跳出for循环
continue; goto label; break;
好了,今天也看了这么多了.其中的内容有和Java类似的.
也有新的书写方式和特性的.本文知识点都在菜鸟收获.
和Java不一样的基础语法,也是看看,在多谢几遍就能记住了.