func main() {
var num1 float64
var num2 float64
var operator byte
num1 = 1.2
num2 = 1.3
operator = '+'
// fmt.Scanln(&num1)
// fmt.Scanln(&operator) // 这里输入错误
fmt.Scanf("%f %c %f", &num1, &operator, &num2)
var res float64 = cal(num1, num2, operator)
fmt.Printf("%f %c %f = %v\n", num1, operator, num2, res)
}
func cal(num1 float64, num2 float64, operator byte) float64 {
var ans float64
switch operator {
case '+':
ans = num1 + num2
case '-':
ans = num1 - num2
case '*':
ans = num1 * num2
case '/':
ans = num1 / num2
}
return ans
}
package main
import (
"fmt"
"go_code/Study_go/Study_go_six/demo02/utils_test"
)
func main() {
num1 := 10.5
num2 := 11.5
num3 := 12.5
opt := '+'
res := utils_test.Cal(num1, num2, byte(opt))
ans := utils_test.AddNum(num1, num2, num3)
fmt.Printf("res: %v\n", res)
fmt.Printf("ans: %v\n", ans)
fmt.Printf("utils_test.Num: %v\n", utils_test.Num)
}
package utils_test
func AddNum(num1 float64, num2 float64, num3 float64) float64 {
return num1 + num2 + num3
}
package utils_test
var Num float64 = 1.1
func Cal(num1 float64, num2 float64, opt byte) float64 {
var ans float64 = 0
switch opt {
case '+':
ans = num1 + num2
case '-':
ans = num1 - num2
case '*':
ans = num1 * num2
case '/':
ans = num1 / num2
}
return ans
}
// 10. 自定义数据类型 类似于别名
type myFunc func(int, int) (int, int)
func main() {
// 6. 地址传递
var num int = 10
fmt.Printf("num: %v\n", num) // 10
test2(&num)
fmt.Printf("num: %v\n", num) // 20
// 8. 函数作为数据类型
var a = test1
fmt.Printf("a: %T\n", a) // a: func(int, int) (int, int)
fmt.Printf("test1: %T\n", test1) // test1: func(int, int) (int, int)
sum, sub := a(10, 20)
fmt.Printf("sum: %v\t sub: %v\n", sum, sub) // sum: 30 sub: -10
// 9. 函数作为形参
sum1, sub1 := test3(a, 20, 30)
fmt.Printf("sum1: %v\t sub1: %v\n", sum1, sub1) // sum1: 50 sub1: -10
// 10. 自定义数据类型 类似于别名
type myInt int
var b myInt = 10
fmt.Printf("b: %v\n", b) // 10
sum2, sub2 := test4(test1, 500, 600)
fmt.Printf("sum2: %v\tsub2: %v\n", sum2, sub2) // sum2: 1100 sub2: -100
// 11. 函数返回值命名 func test1(num1 int, num2 int) (sum int, sub int) {
// 13. 可变参:可变参数放在固定参数后面
sum5 := test5(10, 20, 30, 40, 50)
fmt.Printf("sum5: %v\n", sum5) // sum5: 150
}
func test1(num1 int, num2 int) (sum int, sub int) {
sum = num1 + num2
sub = num1 - num2
return
}
func test2(num *int) {
*num += 10
fmt.Printf("num: %v\n", *num) // 20
}
func test3(funvar func(int, int) (int, int), num1 int, num2 int) (int, int) {
return funvar(num1, num2)
}
func test4(funvar myFunc, num1 int, num2 int) (int, int) {
return funvar(num1, num2)
}
func test5(nums ...int) (sum int) {
for i := 0; i < len(nums); i++ {
sum += nums[i]
}
return
}
package main
import (
"fmt"
"go_code/Study_go/Study_go_six/demo03/functiondemo"
)
func main() {
var num int = 10
test1 := functiondemo.AddOne(num)
fmt.Printf("num: %v\n", num) // 10
fmt.Printf("test1: %v\n", test1) // 11
test2 := functiondemo.AddTwo(&num) // 传递参数地址过去
fmt.Printf("num: %v\n", num) // 11 形参地址的值已经变为11
fmt.Printf("test2: %v\n", test2) // 11
var num1 int = 5
var num2 int = 3
test3, test4 := functiondemo.AddAndSub(num1, num2)
fmt.Printf("test3: %v\n", test3) // 8
fmt.Printf("test4: %v\n", test4) // 2
test5, _ := functiondemo.AddAndSub(num1, num2) // 8
fmt.Printf("test5: %v\n", test5)
_, test6 := functiondemo.AddAndSub(num1, num2) // 2
fmt.Printf("test6: %v\n", test6)
}
package functiondemo
func AddOne(num int) int {
num++
return num
}
func AddTwo(num *int) int {
*num++
return *num
}
// 计算两数加和减, 返回两者的结果
func AddAndSub(num1 int, num2 int) (int, int) {
res1 := num1 + num2
res2 := num1 - num2
return res1, res2
}
func main() {
res1 := f1(5)
fmt.Printf("res1: %v\n", res1) // 120
res2 := f2(5)
fmt.Printf("res2: %v\n", res2) // 8
}
// n!
func f1(num int) int {
if num == 0 || num == 1 {
return 1
}
return num * f1(num-1)
}
// 斐波那契
func f2(num int) int {
if num == 0 || num == 1 {
return 1
}
return f2(num-1) + f2(num-2)
}
package main
import (
"fmt"
temptest "go_code/Study_go/Study_go_six/demo06/tempTest"
)
// 输出结果:
// temptest test
// temptest init
// test function
// init function
// main function
// val: 90
// temptest.Name: wxy
// temptest.Age: 22
var val int = test()
func main() {
fmt.Println("main function")
fmt.Printf("val: %v\n", val)
fmt.Printf("temptest.Name: %v\n", temptest.Name)
fmt.Printf("temptest.Age: %v\n", temptest.Age)
}
// 用于完成初始化操作
func init() {
fmt.Println("init function")
}
func test() int {
fmt.Println("test function")
return 90
}
package temptest
import "fmt"
var Name string = test()
var Age int
func test() string {
fmt.Println("temptest test")
return "wxy"
}
func init() {
Age = 22
fmt.Println("temptest init")
}
func main() {
// 方式1
res1 := func(n1 int, n2 int) int {
return n1 + n2
}(10, 20)
fmt.Printf("res1: %v\n", res1) // res1: 30
// 方式2 基本不用
a := func(n1 int, n2 int) int {
return n1 - n2
}
res2 := a(10, 20)
fmt.Printf("res2: %v\n", res2) // res2: -10
// 多次调用
res3 := a(30, 10)
fmt.Printf("res3: %v\n", res3) // res3: 10
// 3. 调用全局匿名函数
res4 := Fun1(10, 20)
fmt.Printf("res4: %v\n", res4) // res4: 200
}
// 3. 全局匿名函数
var (
// 首字母需要大写
Fun1 = func(num1 int, num2 int) int {
return num1 * num2
}
)
/*
1. AddUpper 是一个函数,返回的类型是 func(int) int
2. 闭包的说明:
var n int = 10
return func(i int) int { 返回一个匿名函数,但是这个匿名函数引用到函数外的n,
因此和这个匿名函数就和n形成了一个整体,构成闭包
n = n + i
return n
}
3. 闭包类似于类,函数是操作,n是字段。函数和它一起组成闭包
4. 当反复调用f时,因为n初始化一次,因此每调用一次就会进行累加,不再进行初始化
5. 关键是分析出返回的函数它使用了(引用)到那些变量
*/
func AddUpper() func(int) int {
var n int = 10
var str string = "hello"
return func(i int) int {
n = n + i
str += "a"
fmt.Printf("str: %v\n", str)
return n
}
}
func main() {
res := AddUpper()
fmt.Printf("res: %T\n", res) // res: func(int) int
fmt.Printf("res: %v\n", res(1)) // 11
fmt.Printf("res: %v\n", res(2)) // 13
fmt.Printf("res: %v\n", res(3)) // 16
}
import (
"fmt"
"strings"
)
func makeSuffix(suffix string) func(str string) string {
return func(str string) string {
if strings.HasSuffix(str, suffix) {
return str
} else {
return str + suffix
}
}
}
func makeSuffix2(suffix string, str string) string {
if strings.HasSuffix(str, suffix) {
return str
} else {
return str + suffix
}
}
func main() {
test := makeSuffix(".jpg")
fileName := test("abc")
fmt.Printf("fileName: %v\n", fileName) // fileName: abc.jpg
fmt.Printf("makeSuffix2(fileName, \"jpg\"): %v\n", makeSuffix2(".jpg", "name"))
//makeSuffix2(fileName, "jpg"): name.jpg
}
/*
输出结果
sum: 26
n2 = 5
n1 = 1
res: 26
*/
func sum(n1 int, n2 int) (sum int) {
// 当执行到defer时,暂时不执行,会将defer后面的语句压入到独立的栈(defer)
// 当函数执行完毕后,再从defer栈,按照先入后出的方式出栈,执行
// 在调用数据库时,会执行很多资源,但是需要在最后进行关闭资源
// 若使用defer的话,即可在调用完直接编写关闭资源
// 这样会更方便
defer fmt.Println("n1 = ", n1) // 1
defer fmt.Println("n2 = ", n2) // 5
n1 += 10
n2 += 10
sum = n1 + n2
fmt.Printf("sum: %v\n", sum) // 26
return
}
func main() {
res := sum(1, 5)
fmt.Printf("res: %v\n", res) // 26
}
func Clone(s string) string
Clone returns a fresh copy of s
func Compare(a, b string) int
Compare returns an integer comparing two strings lexicographically. The result will be 0 if a == b, -1 if a < b, and +1 if a > b.
func Contains(s, substr string) bool
Contains reports whether substr is within s.
func ContainsAny(s, chars string) bool
ContainsAny reports whether any Unicode code points in chars are within s.
func ContainsRune(s string, r rune) bool
ContainsRune reports whether the Unicode code point r is within s.
func Count(s, substr string) int
Count counts the number of non-overlapping instances of substr in s. If substr is an empty string, Count returns 1 + the number of Unicode code points in s.
func EqualFold(s, t string0) bool
EqualFold reports whether s and t, interpreted as UTF-8 strings, are equal under Unicode case-folding, which is a more general form of case-insensitivity.
func Fields(s string) []string
Fields splits the string s around each instance of one or more consecutive white space characters, as defined by unicode.IsSpace, returning a slice of substrings of s or an empty slice if s contains only white space.
func FieldsFunc(s string, f func(rune) bool) []string
FieldsFunc splits the string s at each run of Unicode code points c satisfying f© and returns an array of slices of s. If all code points in s satisfy f© or the string is empty, an empty slice is returned.
func HasPrefix(s, prefix string) bool
func HasPrefix(s, prefix string) bool
HasPrefix tests whether the string s begins with prefix. HasSuffix tests whether the string s ends with suffix.
func Index(s, substr string) int
Index returns the index of the first instance of substr in s, or -1 if substr is not present in s.
func IndexAny(s, chars string) int
func IndexRune(s string, r rune) int
func IndexFunc(s string, f func(rune) bool) int
func IndexByte(s string, c byte) int
IndexRune returns the index of the first instance of the Unicode code point r, or -1 if rune is not present in s. If r is utf8.RuneError, it returns the first instance of any invalid UTF-8 byte sequence.
func Join(elems []string, sep string) string
Join concatenates the elements of its first argument to create a single string. The separator string sep is placed between elements in the resulting string.(将字符串数组以sep为分割符联合成一个字符串)
func LastIndex(s, substr string) int
func LastIndexAny(s, chars string) int
func LastIndexByte(s string, c byte) int
func LastIndexFunc(s string, f func(rune) bool) int
LastIndex returns the index of the last instance of substr in s, or -1 if substr is not present in s.
func Repeat(s string, count int) string
Repeat returns a new string consisting of count copies of the string s.
func Replace(s, old, new string, n int) string
Replace returns a copy of the string s with the first n non-overlapping instances of old replaced by new. If old is empty, it matches at the beginning of the string and after each UTF-8 sequence, yielding up to k+1 replacements for a k-rune string. If n < 0, there is no limit on the number of replacements.
func ReplaceAll(s, old, new string) string
ReplaceAll returns a copy of the string s with all non-overlapping instances of old replaced by new. If old is empty, it matches at the beginning of the string and after each UTF-8 sequence, yielding up to k+1 replacements for a k-rune string.
func Split(s, sep string) []string
Split slices s into all substrings separated by sep and returns a slice of the substrings between those separators.
If s does not contain sep and sep is not empty, Split returns a slice of length 1 whose only element is s.
If sep is empty, Split splits after each UTF-8 sequence. If both s and sep are empty, Split returns an empty slice.
It is equivalent to SplitN with a count of -1.
To split around the first instance of a separator, see Cut.
func ToLower(s string) string
func ToUpper(s string) string
func ToTitle(s string) string
ToUpper returns s with all Unicode letters mapped to their upper case.
func Trim(s, cutset string) string
Trim returns a slice of the string s with all leading and trailing Unicode code points contained in cutset removed.
func Atoi(s string) (int, error)
func Itoa(i int) string
Atoi is equivalent to ParseInt(s, 10, 0), converted to type int.
Itoa is equivalent to FormatInt(int64(i), 10).
func FormatBool(b bool) string
FormatBool returns “true” or “false” according to the value of b.
func FormatFloat(f float64, fmt byte, prec, bitSize int) string
FormatFloat converts the floating-point number f to a string, according to the format fmt and precision prec. It rounds the result assuming that the original was obtained from a floating-point value of bitSize bits (32 for float32, 64 for float64).
The format fmt is one of ‘b’ (-ddddp±ddd, a binary exponent), ‘e’ (-d.dddde±dd, a decimal exponent), ‘E’ (-d.ddddE±dd, a decimal exponent), ‘f’ (-ddd.dddd, no exponent), ‘g’ (‘e’ for large exponents, ‘f’ otherwise), ‘G’ (‘E’ for large exponents, ‘f’ otherwise), ‘x’ (-0xd.ddddp±ddd, a hexadecimal fraction and binary exponent), or ‘X’ (-0Xd.ddddP±ddd, a hexadecimal fraction and binary exponent).
The precision prec controls the number of digits (excluding the exponent) printed by the ‘e’, ‘E’, ‘f’, ‘g’, ‘G’, ‘x’, and ‘X’ formats. For ‘e’, ‘E’, ‘f’, ‘x’, and ‘X’, it is the number of digits after the decimal point. For ‘g’ and ‘G’ it is the maximum number of significant digits (trailing zeros are removed). The special precision -1 uses the smallest number of digits necessary such that ParseFloat will return f exactly.
func FormatInt(i int64, base int) string
FormatInt returns the string representation of i in the given base, for 2 <= base <= 36. The result uses the lower-case letters ‘a’ to ‘z’ for digit values >= 10.
func FormatUint(i uint64, base int) string
FormatUint returns the string representation of i in the given base, for 2 <= base <= 36. The result uses the lower-case letters ‘a’ to ‘z’ for digit values >= 10.
func ParseBool(str string) (bool, error)
ParseBool returns the boolean value represented by the string. It accepts 1, t, T, TRUE, true, True, 0, f, F, FALSE, false, False. Any other value returns an error.
func ParseFloat(s string, bitSize int) (float64, error)
func ParseInt(s string, base int, bitSize int) (i int64, err error)
func ParseUint(s string, base int, bitSize int) (uint64, error)
import (
"fmt"
"math/rand"
"time"
)
func main() {
// 1. 获取当前时间
now := time.Now()
fmt.Printf("now: %v\n %T \n", now, now)
// 2. 获取当前时间的年月日 时分秒
year := now.Year()
fmt.Printf("year: %v\n", year)
month := now.Month()
fmt.Printf("month: %v\n", month)
day := now.Day()
fmt.Printf("day: %v\n", day)
hour := now.Hour()
fmt.Printf("hour: %v\n", hour)
minute := now.Minute()
fmt.Printf("minute: %v\n", minute)
second := now.Second()
fmt.Printf("second: %v\n", second)
// 3. 格式化日期和时间 2006 01 02 15 04 05 固定写法
s1 := now.Format("2006-01-02 15:04:05")
s2 := now.Format("2006 - 01 - 02")
s3 := now.Format("15 : 04 : 05")
fmt.Printf("s1: %v\n", s1)
fmt.Printf("s2: %v\n", s2)
fmt.Printf("s3: %v\n", s3)
// 4. time中的常量
fmt.Printf("time.Nanosecond: %v\n", time.Nanosecond) // time.Nanosecond: 1ns
fmt.Printf("time.Microsecond: %v\n", time.Microsecond) // time.Microsecond: 1µs
fmt.Printf("time.Millisecond: %v\n", time.Millisecond) // time.Millisecond: 1ms
fmt.Printf("time.Second: %v\n", time.Second) // time.Second: 1s
fmt.Printf("time.Minute: %v\n", time.Minute) // time.Minute: 1m0s
fmt.Printf("time.Hour: %v\n", time.Hour) // time.Hour: 1h0m0s
for i := 0; i < 100; i++ {
fmt.Printf("i: %v\t", i)
time.Sleep(time.Millisecond * 10) // 时间常量不能使用float
}
// 4. 获取时间戳
fmt.Printf("now.Unix(): %v\n", now.Unix()) // now.Unix(): 1650337607
fmt.Printf("now.UnixNano(): %v\n", now.UnixNano()) // now.UnixNano(): 1650337607734718000
for i := 0; i < 10; i++ {
t := now.UnixNano()
rand.Seed(t)
num := rand.Intn(10) + 1
fmt.Printf("num: %v\n", num)
}
// 5. 时间
start := time.Now().Unix()
for i := 0; i < 1000; i++ {
time.Sleep(time.Millisecond)
}
end := time.Now().Unix()
costTime := end - start
fmt.Printf("costTime: %v\n", costTime)
}
func len(v Type) int
内建函数len返回 v 的长度,这取决于具体类型:
数组:v中元素的数量
数组指针:*v中元素的数量(v为nil时panic)
切片、映射:v中元素的数量;若v为nil,len(v)即为零
字符串:v中字节的数量
通道:通道缓存中队列(未读取)元素的数量;若v为 nil,len(v)即为零
func new(Type) *Type
内建函数new分配内存。其第一个实参为类型,而非值。其返回值为指向该类型的新分配的默认值的指针。
func main() {
var num int = 10
// num: 10 int 0xc0000b2008
fmt.Printf("num: %v \t %T \t %v \n", num, num, &num)
num1 := new(int) // 分配内存--指针
*num1 = 10
// num1: 0xc0000b2018 *int 0xc0000ac020 10
fmt.Printf("num1: %v \t %T \t %v \t %v \n", num1, num1, &num1, *num1)
num2 := new(int)
num2 = &num
*num2 = 20
fmt.Printf("num2: %v\t %v\n", *num2, num2) // num2: 20 0xc0000160a0
}
func make(Type, size IntegerType) Type
内建函数make分配并初始化一个类型为切片、映射、或通道的对象。其第一个实参为类型,而非值。make的返回类型与其参数相同,而非指向它的指针。其具体结果取决于具体的类型:
切片:size指定了其长度。该切片的容量等于其长度。切片支持第二个整数实参可用来指定不同的容量;
它必须不小于其长度,因此 make([]int, 0, 10) 会分配一个长度为0,容量为10的切片。
映射:初始分配的创建取决于size,但产生的映射长度为0。size可以省略,这种情况下就会分配一个
小的起始大小。
通道:通道的缓存根据指定的缓存容量初始化。若 size为零或被省略,该信道即为无缓存的。
func New(text string) error
使用字符串创建一个错误,请类比fmt包的Errorf方法,差不多可以认为是New(fmt.Sprintf(...))。
import (
"errors"
"fmt"
)
func test() {
// 延迟处理
defer func() { // 你们函数
// 捕获异常
err := recover()
if err != nil {
// err: runtime error: integer divide by zero
fmt.Println("err:", err)
// 抛出异常
// panic(err)
}
}()
num1 := 10
num2 := 0
div := num1 / num2
fmt.Printf("div: %v\n", div)
}
func readConf(name string) (err error) {
if name == "config.init" {
return nil
} else {
return errors.New("Read File error")
}
}
func test2() {
err := readConf("config2.init")
if err != nil {
// 抛出异常,终止运行
panic(err) // panic: Read File error
}
fmt.Println("test2 test2")
}
func main() {
test()
fmt.Println("main...")
test2()
fmt.Println("test2 main")
}