//go语言语法细节

package main

import "fmt"




func test1(){
   var a int
   var s string


   //go语言要求,每一个变量被申明的时候必须要赋初值,a这个时候是0,s是空串""
   //如果变量被申明那么一定要被引用,不然就不能通过编译
   fmt.Println(a,s) //打印不出来s的值,s是空串,
   fmt.Printf("%d,,,,,%q",a,s) //%q 会打印出字符串的引号

   ///////////////////////////////////////////////////////////////////

   var b, c int = 1, 2
   var str string = "string"
   fmt.Println(b,c,str) //如上,变量赋值方式。

   /////////////////////////////////////////////////////////////////////

   var  d, e  = 1, 2;
   var string = "string value"
   fmt.Println(d,e,string)//关键字其实可以省略,他可以通过后面的类型自动判断数据类型

   ////////////////////////////////////////////////////////////////////

   //那么我是不是可以这样玩儿呢?
   var m,n,o,p,q = 1,2,"str",true,3.14
   fmt.Println(m,n,o,p,q)//一次定义中有各种的类型,也是支持的。

   ////////////////////////////////////////////////////////////////////

   //然后变量的定义,可以省略var,于是有
   aa, bb, cc,  dd, ee := 1,2,"str",true,3.14 //加个冒号
   bb = 1 //这是对已经声明的变量重新复制不能有冒号
   fmt.Println(aa,bb,cc,dd,ee)//你看,很灵性

   //接下来看函数外面,我将进行全局变量的定义
}

var theaa = 1
var thess = "str"
//thebb := 1   这种写法是错的,这种变量不能这样写,错了。
//重点说一句,这两个变量不是全局变量,这只是一个包内部的变量,go语言没有全局变量额说法,都是以包内部这种
//他的作用域只是包内部

//为了不写很多var,可以这样写哦
var(//注意是括号
   vi, vb= 1, 3//嗯,没得问题
   va = "a" //这里哦
)//这里的一群变量,嗯,这种也支持函数内部

var vvi, vva = 1, "aa";//嗯,基本规则没有问题

//咳咳,发现没有,全局变量没有被引用哦,前面说的规定,自己打脸了撒

func main() {
   fmt.Print("hello world")
   test1()
   fmt.Println(vi,vb,va,vvi,vva,theaa,thess) //全局的引用
}


//go语言数据类型
package main

import (
   "fmt"
   "math/cmplx"
   "math"
)

//go语言的内建变量类型,咳咳,今天我才搞懂,什么是内建变量,就是语言内置类型,也就是基本数据类型
//bool, string
//(u)int,(u)int8,(u)int16,(u)int32,(u)int64,uintptr(加了u就是无符号的意思)
//byte,rune(这是啥,这就是c,java中的char,字符型,为了应对多国语言的一个字符,采用rune,他是4个字节的)
//float32, float64, complex64, complex128 //看见了新生的东西,顿时产生敬仰之情,
//           complex是复数,他有实部与虚部,可以表示一个二维平面的数(数学之美),float是浮点数,明确说出了他的位数
//
//       来我们来回一下复数的知识,   3 + 4i  ->  这就表示了一个点,长度是5,
//          emm,接下来,e ^ (a*i)= cos a + i sin a --> 表示一个圆,a是一个角度  ,,这个公式会是高等数学里面的泰勒基数展开,
//          上面的这个圆的长度都为1,而且e^(a * i)也是周期函数,emmmm,讲不下去了,不讲了可以吗?
//          嗯,最后一句,  e(i * pi) + 1 = 0 这是欧拉公式。
//       嗯,骚年,是时候去认真回顾下高等数学了。

func main() {
   //上面讲了一大堆,首先,复数
   c := 3 + 4i  //记住了,这个4i必须连着写,中间不能有乘号什么的。
   a := cmplx.Abs(c) //计算长度

   fmt.Println(c)  //(3+4i)
   fmt.Println(a)  //5
   //fmt.Println("这个复数的长度为" + a)         // java的这种写法不对了吗?

   //这里来一个欧拉公式
   oula()


   //go语言的类型转换,go语言不存在隐式类型转换,全是强制转换
   var aaa, bbb int = 1 ,2
   var ccc int
   ccc = int(math.Sqrt(float64(aaa * aaa + bbb * bbb))) //强制转换
   fmt.Println(ccc)

   //遗留问题,强制转换的时候,很多语言都存在的问题,浮点数表示并不准确,那么4.99999999999999999999这种,本来浮点是5,但是取整结果却是4哦
   //怎么办?这个明天再说
}

func oula(){
   fmt.Println(cmplx.Pow(math.E,1i * math.Pi) + 1) //(0+1.2246467991473515e-16i)
   fmt.Println(math.Exp(1i * math.Pi) + 1) //与上面一样
   //这里不是0,虚部是一个很小的浮点数,所以结果只是接近0,负数的实部虚部都是两个等长的浮点型数据,结果与python一样
}

//最后还想说下,每一个go语言文件,如果想要运行起来,文件上面必须得下package main,这样文件内部的main函数才会作为入口可以执行。