⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 blog.csdn.net/tiantang_zy/article/details/105048817 「天堂里外」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

面试了一个单位 说可能需要java转go语言 所以在此开始学习一下 如果面试通过了就继续学 没面试过 那么就这一篇了 加油!!!

01、万能之Hello World 开启go的大门

直接上代码

package main //表明包

import "fmt" //导入包 fmt 控制输入输出 感觉和java的System.out和Scanner有点像

func main() {
fmt.Println("Hello Go world。"); //进入这个世界了
}

输出结果:

是不是感觉还可以。

02、Go语言环境安装

安装包下载地址为:https://golang.org/dl/。

如果打不开可以使用这个地址:https://golang.google.cn/dl/。

我安装的是windows版的 双击安装选择目录 全程轻松随意 比想象中简单

配置系统变量,然后就可以开始玩了

03、基础语法

  • 行分割符:不需要像java一眼每句之后都加一个;表明结束 每一行都是单独的一句 如果非要把几行语句写在一起 就需要加分号了

  • 注释 : //单行注释 /* aaa bbb */

  • 标识符 标识符用来命名变量、类型等程序实体。一个标识符实际上就是一个或是多个字母(AZ和az)数字(0~9)、下划线_组成的序列,但是第一个字符必须是字母或下划线而不能是数字。

  • 字符串连接 直接用+号即可连接 这点倒是和java挺像的 但是java里直接用加号连接的性能不是很好 不知道go语言中是否有相类似的编译流程

  • 关键字

  • 预定义标识符

04、数据类型

数据类型详细的可以看这个:https://www.runoob.com/go/go-data-types.html 首先一点,给我印象比较深的就是 对数字类型添加了很多的包装,在不同的应用范围内使用不同的数据类型 例如

  • int8 有符号 8 位整型 (-128 到 127)
  • int16 有符号 16 位整型 (-32768 到 32767)
  • int32 有符号 32 位整型 (-2147483648 到 2147483647)
  • int64 有符号 64 位整型 (-9223372036854775808 到 9223372036854775807) 这个给人感觉就是对使用着感觉 有了更高的要求 像java就是int Integer BigInteger这几种包装好的用就行了 当然这样要求的更细致 感觉编译的时候 就越容易控制 如果方方面面都这么细致的话 运行速度上就可以提高不少的

05、声明变量

  1. var identifier type 例:var a int;
  2. var identifier1,identifier2 type 例:var a,b string;
  3. 指定变量类型,如果没有初始化,则变量默认为零值 数值类型(包括complex64/128)为 0 布尔类型为 false 字符串为 “”(空字符串) 以下几种类型为 nil:var a *int var a []int var a map[string] int var a chan int var a func(string) int var a error // error 是接口
  4. 根据值自行判定变量类型 例:var d = true (这点就有点像js了)
  5. 省略 var, 注意 := 左侧如果没有声明新的变量,就产生编译错误,格式:v_name := value 例:f := “Runoob”
  6. 多变量声明

//类型相同多个变量, 非全局变量
var vname1, vname2, vname3 type
vname1, vname2, vname3 = v1, v2, v3

// 和 python 很像,不需要显示声明类型,自动推断
var vname1, vname2, vname3 = v1, v2, v3

// 出现在 := 左侧的变量不应该是已经被声明过的,否则会导致编译错误
vname1, vname2, vname3 := v1, v2, v3


// 这种因式分解关键字的写法一般用于声明全局变量
var (
vname1 v_type1
vname2 v_type2
)

06、常量

const 定义常量关键字 目前感觉和final static 类似 定义了之后就不能改了 如果代码里面改了的话 会报 cannot assign to LENGTH 错误

下来就发现一个神奇懂东西 iota iota,特殊常量,可以认为是一个可以被编译器修改的常量。

iota 在 const关键字出现时将被重置为 0(const 内部的第一行之前),const 中每新增一行常量声明将使 iota 计数一次(iota 可理解为 const 语句块中的行索引)。

枚举自增计数器 感觉是这么个意思

07、运算符

&这个就是只有两个1的时候才是1其余都是0 |这个是只有两个0的时候才是0其余都是1和与刚好相反 ^这个简单粗暴两个相同的数字是0不同的时候是1

这个<<=后面的几个都还有点惊艳到我了 厉害厉害

这两个优点没太看懂 敲个代码试一下

package main

import "fmt"

func main(){
var a string = "abc"
var ptr *string = &a
fmt.Printf("第 1 行 - a 变量类型为 = %T\n", a );
fmt.Printf("第 2 行 - ptr 变量类型为 = %T\n", ptr );
fmt.Println(*ptr)
fmt.Println(ptr)
}

加*输出的是内容 不加输出的就是地址 这个指针的概念 java里是没有的

这一part 感觉除了指针的概念 其余的感觉都差不多 详细例子:https://www.runoob.com/go/go-constants.html

08、条件语句

这个select语句真的是看的我欲生欲死 以下描述了 select 语句的语法:

每个 case 都必须是一个通信 所有 channel 表达式都会被求值 所有被发送的表达式都会被求值 如果任意某个通信可以进行,它就执行,其他被忽略。如果有多个 case 都可以运行,Select 会随机公平地选出一个执行。其他不会执行。否则:如果有 default 子句,则执行该语句。如果没有 default 子句,select 将阻塞,直到某个通信可以运行;Go 不会重新对 channel 或值进行求值。

来来来 两段代码说明一下

package main

import (
"fmt"
)

func fibonacci(c, quit chan int) {
x, y := 1, 1

for {
select {
case c <- x:
fmt.Printf("x : %d, y : %d\n", x, y)
x, y = y, x+y
case <-quit:
fmt.Println("quit")
return
}
}
}

func main() {
c := make(chan int)
quit := make(chan int)

go func() {
for i := 0; i < 6; i++ {
fmt.Printf("开始搞事 i = %d\n", i)
fmt.Println(<-c)
}
quit <- 0
}()

fibonacci(c, quit)
}

输出结果为:

第二段代码:

package main

import (
"fmt"
"time"
)

func Chann(ch chan int, stopCh chan bool) {
for j := 0; j < 10; j++ {
ch <- j
time.Sleep(time.Second)
}
stopCh <- true
}

func main() {

ch := make(chan int)
c := 0
stopCh := make(chan bool)

go Chann(ch, stopCh)

for {
select {
case c = <-ch:
fmt.Println("Recvice", c)
fmt.Println("channel")
case s := <-ch:
fmt.Println("Receivessss", s)
case _ = <-stopCh:
goto end
}
}
end:
}

输出结果为:

这两个例子分别说明了下面两点 如果任意某个通信可以进行,它就执行,其他被忽略。如果有多个 case 都可以运行,Select 会随机公平地选出一个执行。其他不会执行。

但是有个疑问 为啥第一个例子里在执行偶数次的时候 xy会交换两次 在下一次调用的时候又不会进行交换?内部是怎么实现的???真想打个断点调试一下 这个问题如果我往后会做go的话 我一定会回来的!!!!

今天就学到这里了

文章目录
  1. 1. 01、万能之Hello World 开启go的大门
  2. 2. 02、Go语言环境安装
  3. 3. 03、基础语法
  4. 4. 04、数据类型
  5. 5. 05、声明变量
  6. 6. 06、常量
  7. 7. 07、运算符
  8. 8. 08、条件语句