内建变量类型有:
func variableZeroValue(){
// 定义变量,初始化,合理的初始值
// 在C中未初始化的局部变量(自动变量)初始值随机分配,不确定的,而全局变量 、静态变量初始值为0
// 在java中未初始化的成员变量有默认值,而局部变量没有默认值
var a int
var s string
fmt.Print(a, s)
fmt.Printf("\n%d %q\n", a, s)
}
注
Println 打印的每一项之间都会有空格,Print 没有
Println 会自动换行,Print 不会
Printf 是格式化输出,需要占位符
func variableInitialValue(){
// 变量初始化
var a, b int = 3, 4
var s string = "Helle Go"
fmt.Println(a, b, s)
}
注
包内变量是指定义和初始化在函数外,在包内的变量。其作用域在整个包内;
函数内变量是指定义和初始化在函数内的变量,作用域在函数内,不能作用在整个包内。
func variableTypeDeduction(){
// 省略变量定义类型,由计算机自动判断识别
var a, b, c, s = 3, 4, true, "def"
fmt.Println(a, b, c, s)
}
func variableShorter(){
// 简单写法
// 变量在定义时初始化即第一次对变量进行操作时用:=,这里省略关键词var
// :=仅仅在函数内使用,在定义包内部变量时不能使用
a, b, c, s := 3, 4, true, "shorter"
// 第二次对变量进行操作时,就能不使用:=
b = 5
fmt.Println(a, b, c, s)
}
注
变量可以使用变量组来减少写var关键字,如下列代码
var (
bb = 4
gg = "Hello Go"
)
// 等效于
var bb int = 4
var gg string = "Hello Go"
func euler(){
//c := 3 + 4i
//// 取模
//fmt.Println(cmplx.Abs(c))
//使用1i表示虚部i。如果直接使用i的话,会被认为变量i而非虚部i。
//欧拉公式 表示方法一
fmt.Println(
cmplx.Pow(math.E, 1i * math.Pi) + 1)
//欧拉公式 表示方法二
fmt.Println(
cmplx.Exp(1i * math.Pi) + 1)
}
int main()
{
int a = 5;
float b = 3;
printf("%f",a*b);
}
func triangle(){
var a, b int = 3, 4
var c int
c = int(math.Sqrt(float64(a * a + b * b)))
fmt.Println(c)
}
func consts(){
//// 常量的作用相当于是文本替换的作用
//const filename = "Goland.txt"
//const a, b = 3, 4
//// 这里若将a,b定义数据类型,则下面在Sqrt中需要进行强制类型转化为float64
//// 常量const数值可以作为各种类型使用
const ( //常量可以定义在一组中
filename = "Goland.txt"
a, b = 3, 4
)
var c int
c = int(math.Sqrt(a * a + b * b))
fmt.Println(filename, c)
}
const(
cpp = 0
java = 1
python = 2
goland = 3
)
fmt.Println(cpp, java, python, goland)
const (
cpp = iota + 10
_
python
goland
javascript
)
fmt.Println(cpp, javascript, python, goland)
// 输出结果是常量自增,不需要每个赋值
// b, kb, mb, gb, tb, pb
const (
b = 1 << (10 * iota) //左移动10位,即扩大1024倍
kb
mb
gb
tb
pb
)
fmt.Println(b, kb, mb, gb, tb, pb)
const (
aa = 97
bb
cc
)
fmt.Println(aa, bb, cc)
if 条件 {
} else if 条件{
} else {
}
const filename = "Golang.txt"
//contents, err := ioutil.ReadFile(filename) // 读取文件,访问文件内容byte数组和出错信息
//if err != nil {
// fmt.Println(err)
//} else {
// fmt.Printf("%s\n", contents)
//}
if contents, err := ioutil.ReadFile(filename); err != nil {
fmt.Println(err)
}else {
fmt.Printf("%s\n", contents)
}
// if外不能使用变量contents
// fmt.Printf("%s\n", contents) 这里contents会报错,contents生存期在if中,在if外不能使用contents
switch 表达式 {
case 表达式一:
语句一
case 表达式二:
语句二
...
default:
}
Goland中switch会自动break,除非使用fallthrough;
switch通常执行一个case后会立即退出swithc,case后的fallthrough语句表明执行完当前 case 语句之后按顺序执行下一个case 语句;
swithc后可以不跟表达式,相当与switch true,将case中的表达式与true比较,相等执行;
多个有相同值的 case 是不允许的;
case后的表达式可以有多个,用逗号分隔。
switch语句案例
func grade(score int) string {
g := ""
switch {
case score < 0 || score > 100:
panic(fmt.Sprintf(
"Wrong score: %d", score))
case score < 60:
g = "E"
case score < 70:
g = "D"
case score < 80:
g = "C"
case score < 90:
g = "B"
case score <= 100:
g = "A"
}
return g
}
循环语句for的格式
for 初始条件; 结束条件; 递增表达式 {
}
// 例
sum := 0
for i := i; i <= 100; i++ {
sum += i
}
// 十进制转二进制案例
func convertToBin(n int) string{
result := ""
for ; n > 0; n /= 2 {
lsb := n % 2 // 取模
result = strconv.Itoa(lsb) + result
}
return result
}
条件语句和循环语句要点回顾
函数的案例
func eval(a, b int, op string) (int, error) {
switch op {
case "+":
return a + b, nil
case "-":
return a - b, nil
case "*":
return a * b, nil
case "/":
//return a / b
q, _ := div(a, b) // go中定义的变量必须使用,这里使用_表明第二个字段r不想被定义出来
return q, nil
default:
return 0, fmt.Errorf("unsupported operation: %s" + op)
}
}
// 带余数除法 13 / 3 = 4 ... 1
//func div(a, b int) (int, int){
// return a / b, a % b
//}
func div(a, b int) (q, r int){
//q = a / b
//r = a % b
//return q, r
return a / b, a % b
}
// 函数式编程
func apple(op func(int, int) int, a, b int) int {
p := reflect.ValueOf(op).Pointer() //反射,获取指针
opName := runtime.FuncForPC(p).Name() //获得操作的名字,通过函数名执行对应的函数
fmt.Println("Calling function %s with args " + "(%d, %d)\n", opName, a, b)
return op(a, b)
}
func pow(a, b int) int {
return int(math.Pow(float64(a), float64(b)))
}
// 可变参数列表
func sum(numbers ...int) int {
s := 0
for i := range numbers {
s += numbers[i]
}
return s
}
func main(){
fmt.Println(
eval(3, 4, "*"),
)
// 多返回值的函数
fmt.Println(
div(13, 3),
)
q, r := div(13, 3)
fmt.Println(q, r)
// 带error返回值的函数
if result, err := eval(9,4, "/"); err != nil {
fmt.Println("Error", err)
} else {
fmt.Println(result)
}
// 函数式编程一
fmt.Println(apple(pow, 3, 4))
// 函数式编程二 通过匿名函数来实现的
fmt.Println(apple(
func(a int, b int) int {
return int(math.Pow(
float64(a), float64(b)))
}, 3, 4),
)
// 可变参数列表的案例
fmt.Println(sum(1, 2, 3, 4, 5))
}
指针的定义和赋值
var a int = 2
var pa *int = &a // pa指向变量a的位置
*pa = 3 // a的值为3
fmt.Println(a) // 3
注
值传递:将变量值拷贝一份传递给函数,在函数中无论对值传递参数怎么操作,多不会影响原来的变量;
引用传递:将变量的地址传递给函数,在函数中可以对原变量进行操作;
在java和python中除了内建类型外,自定义的函数参数一般都是应用传递。
实现引用传递案例
func swap(a, b *int) {
*b, *a = *a, *b // 将a指向的内容和b指向的内容进行交换
}
func main() {
a, b := 3, 4
swap(&a, &b) // 取a,b的地址
fmt.Println(a, b)
}
基础语法就此结束