golang笔记02--golang基础语法

1 介绍

本文继上文 golang笔记01–golang基础配置, 进一步了解 golang 基础语法和相应注意事项。
具体包括 : 变量定义 ,内建变量类型,常量与枚举,条件语句,循环,函数,指针 等基础语法。

2 基础语法

2.1变量定义

变量要点:
  1)变量类型写在变量名后面
  2)编译器可以推测变量类型
  3)没有char,只有rune(32位)
  4)原生支持复数类型

package main

import "fmt"

// 包内部的变量,而非全局变量
var (
	aa = 3
	bb = 4
	cc = "cc"
)

func variableZeroValue() {
	var a int
	var s string
	fmt.Printf("%d %q\n", a, s)
}

func variableInitValue() {
	var a, b int = 3, 4
	var s string = "abc"
	fmt.Println(a, b, s)
}

func variableTypeDeduction() {
	var a, b, c, s = 3, 4, true, "def"
	fmt.Println(a, b, c, s)
}

func variableShorter() {
    // := 定义的变量只能在函数内使用
	a, b, c, s := 3, 4, true, "def"
	b = 5
	fmt.Println(a, b, c, s)
}

func main() {
	fmt.Println("hello world")
	variableZeroValue()
	variableInitValue()
	variableTypeDeduction()
	variableShorter()
	fmt.Println(aa, bb, cc)
}
输出:
hello world
0 ""
3 4 abc
3 4 true def
3 5 true def
3 4 cc

2.2 内建变量类型

常见类型包括:
bool, string
int int8, int16, int32, int64, uintptr
byte, rune(go 的字符类型)
float32 float64 complex64(复数) complex128
强制类型转换,go没有隐式转换

package main

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

func euler() {
	fmt.Println("euler")
	c := 3 + 4i
	fmt.Println(cmplx.Abs(c))
	fmt.Printf("%3f\n", cmplx.Exp(1i*math.Pi)+1)
}

func triangle() {
	fmt.Println("triangle")
	var a, b int = 3, 4
	var c int
	c = int(math.Sqrt(float64(a*a + b*b)))
	fmt.Println(c)
}
func main() {
	fmt.Println("chapter2.2")
	euler()
	triangle()
}
输出:
chapter2.2
euler
5
(0.000000+0.000000i)
triangle
5

2.3 常量与枚举

常量:通过 const 来定义
枚举:通过一组const来定义枚举

package main

import "fmt"

func consts() {
	// 常量名称一般不大写
	const filename = "test.txt"
	const a, b = 3, 4
	const (
		c, d = 5, 6
		flag = true
	)
	fmt.Println(filename, a, b, c, d, flag)
}

func enums() {
	const (
		cpp    = 0
		java   = 1
		python = 2
	)
	fmt.Println(cpp, java, python)
	// 通过iota实现自增值
	const (
		cpp1 = iota
		java1
		python1
	)
	fmt.Println(cpp1, java1, python1)
	const (
		b = 1 << (10 * iota)
		kb
		mb
		gb
		tb
		pb
	)
	fmt.Println(b, kb, mb, gb, tb, pb)
}

func main() {
	consts()
	enums()
}
输出:
test.txt 3 4 5 6 true
0 1 2
0 1 2
1 1024 1048576 1073741824 1099511627776 1125899906842624

2.4 条件语句

go 中的条件语句主要包括if, else, switch;
if 后面的条件没有括号;
if 条件里面也可以定义变量;
switch 不需要break,也可以直接switch多个条件;

package main

import (
	"fmt"
	"io/ioutil"
)

func bounded(v int) int {
	// if 条件式不需要括号的
	if v > 100 {
		return 100
	} else if v < 0 {
		return 0
	} else {
		return v
	}
}

func readFile() {
	const filename = "abc.txt"
	contents, err := ioutil.ReadFile(filename)
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Printf("%s", contents)
	}
}

func calculator(a, b int, op string) int {
	// switch 的 case 会自动 break,不需要单独添加
	// 若 switch 中没有表达式,则可以在 case 中增加条件
	var result int
	switch op {
	case "+":
		result = a + b
	case "-":
		result = a - b
	case "*":
		result = a * b
	case "/":
		result = a / b
	default:
		panic("unsupported operator:" + op)
	}
	return result
}

func main() {
	fmt.Println("chapter 2.4")
	fmt.Println(bounded(50))
	readFile()
	fmt.Println(calculator(1, 15, "+"))
}

2.5 循环

golang 中通过 for 实现循环,没有while;
for 后面的条件没有括号;

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"time"
)

func convert2bin(n int) string {
	// 省略初始条件
	result := ""
	for ; n > 0; n /= 2 {
		lsb := n % 2
		result = strconv.Itoa(lsb) + result
	}
	return result
}

func printFile(filename string) {
	// for 中省略起始 和 递增条件
	file, err := os.Open(filename)
	if err != nil {
		panic(err)
	}
	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		fmt.Println(scanner.Text())
	}
}

func forever() {
	// 不添加如何内容即为死循环
	for {
		fmt.Println("abc")
		time.Sleep(time.Second * 1)
	}
}

func main() {
	fmt.Println(convert2bin(5))
	fmt.Println(convert2bin(13))
	printFile("2.5.txt")
	forever()
}
输出:
101
1101
line 001
line 002
abc
abc
......

2.6 函数

函数语法要点:
  1)返回值类型写在最后面
  2)可以返回多个值
  3)函数作为参数
  4)没有默认参数,可选参数

package main

import (
	"fmt"
	"math"
	"reflect"
	"runtime"
)

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 "/":
		q, _ := div(a, b)
		return q, nil
	default:
		// panic("unsupported operator:" + op)
		return 0, fmt.Errorf("unsupported operator: %s" + op)
	}
}

func div(a, b int) (q, r int) {
	// return a / b, a % b
	q = a / b
	r = a % b
	return q, r
}

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 apply(op func(int, int) int, a, b int) int {
	// 函数式编程
	p := reflect.ValueOf(op).Pointer()
	opName := runtime.FuncForPC(p).Name()
	fmt.Printf("Calling function %s with args (%d, %d) ", opName, a, b)
	return op(a, b)
}

func main() {
	fmt.Println(eval(3, 4, "x"))
	fmt.Println(eval(13, 4, "/"))
	q, r := div(13, 4)
	fmt.Println(q, r)
	fmt.Println(apply(pow, 3, 4))
	fmt.Println(apply(
		func(a int, b int) int {
			return int(math.Pow(float64(a), float64(b)))
		}, 2, 4))
	fmt.Println(sum(1, 2, 3, 4))
}
输出:
0 unsupported operator: %!s(MISSING)x
3 <nil>
3 1
Calling function main.pow with args (3, 4) 81
Calling function main.main.func1 with args (2, 4) 16
10

2.7 指针

go 语言函数使用值传递,但使用指针参数可以实现引用的功能;

package main

import "fmt"

func swap(a, b int) {
	// 值传递
	a, b = b, a
}

func swap_ptr(a, b *int) {
	// 指针传递
	*a, *b = *b, *a
}

func main() {
	fmt.Println("chapter 2.7")
	a, b := 3, 4
	swap(a, b)
	fmt.Println(a, b)
	swap_ptr(&a, &b)
	fmt.Println(a, b)
}
输出:
chapter 2.7
3 4
4 3

3 注意事项

  1. 如何处理float 转 int 4.9999 转换为 4 的情况
    var a float32 = 4.999999
    fmt.Println(int(a))
    可以使用 decimal 包 来解决精度丢失问题
    

4 说明

  1. 软件环境
    go版本:go1.15.8
    操作系统:Ubuntu 20.04 Desktop
    Idea:2020.01.04
  2. 参考文档
    由浅入深掌握Go语言–慕课网
    go 语言编程–许式伟
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

昕光xg

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值