zoukankan      html  css  js  c++  java
  • Go语言系列之基础函数和流程控制

    一、strings和strconv的使用

    • 1. strings.HasPrefix(s string, prefix string) bool:判断字符串s是否以prefix开头 。

    • 2. strings.HasSuffix(s string, suffix string) bool:判断字符串s是否以suffix结尾。

    • 3. strings.Index(s string, str string) int:判断str在s中首次出现的位置,如果没有出现,则返回-1

    • 4. strings.LastIndex(s string, str string) int:判断str在s中最后出现的位置,如果没有出现,则返回-1

    • 5. strings.Replace(str string, old string, new string, n int):字符串替换

    • 6. strings.Count(str string, substr string)int:字符串计数

    • 7. strings.Repeat(str string, count int)string:重复count次str

    • 8. strings.ToLower(str string)string:转为小写

    • 9. strings.ToUpper(str string)string:转为大写

    • 10. strings.TrimSpace(str string):去掉字符串首尾空白字符

    • 11. strings.Trim(str string, cut string):去掉字符串首尾cut字符

    • 12. strings.TrimLeft(str string, cut string):去掉字符串首cut字符

    • 13. strings.TrimRight(str string, cut string):去掉字符串首cut字符

    • 14. strings.Field(str string):返回str空格分隔的所有子串的slice

    • 15. strings.Split(str string, split string):返回str split分隔的所有子串的slice

    • 16. strings.Join(s1 []string, sep string):用sep把s1中的所有元素链接起来

    • 17. strings.Itoa(i int):把一个整数i转成字符串

    • 18. strings.Atoi(str string)(int, error):把一个字符串转成整数

    练习1:判断一个url是否以http://开头,如果不是,则加上http://,判断一个路径是否以“/”结尾,如果不是,则加上/。

    package main
    
    import (
        "fmt"
        "strings"
    )
    
    func urlProcess(url string) string {
        result := strings.HasPrefix(url, "http://")
        if !result {
            url = fmt.Sprintf("http://%s", url)
        }
        return url
    }
    func pathProcess(path string) string {
        result := strings.HasSuffix(path, "/")
        if !result {
            path = fmt.Sprintf("%s/", path)
        }
        strings.Replace()
        return path
    
    }
    
    func main() {
        var (
            url  string
            path string
        )
    
        fmt.Printf("请输入一个url地址和path路径:")
        fmt.Scanf("%s%s", &url, &path)
    
        url = urlProcess(url)
        path = pathProcess(path)
    
        fmt.Println(url)
        fmt.Println(path)
    }
    
    // 请输入一个url地址和path路径: www.baidu.com c:/python
    练习一

    练习2:写一个函数分别演示Replace、Count、Repeat、ToLower、ToUpper等的用法

    package main
    
    import (
        "fmt"
        "strconv"
        "strings"
    )
    
    func main() {
        str := "   hello world abc   
    "
        result := strings.Replace(str, "world", "you", 1)
        fmt.Println("replace:", result)
    
        count := strings.Count(str, "l")
        fmt.Println("count:", count)
    
        result = strings.Repeat(str, 3)
        fmt.Println("repeat:", result)
    
        result = strings.ToLower(str)
        fmt.Println("tolower:", result)
    
        result = strings.ToUpper(str)
        fmt.Println("toupper:", result)
    
        result = strings.TrimSpace(str)
        fmt.Println("trimspace:", result)
    
        result = strings.Trim(str, " 
    
    ")
        fmt.Println("trim", result)
    
        result = strings.TrimLeft(str, " 
    
    ")
        fmt.Println("trimleft:", result)
    
        result = strings.TrimRight(str, " 
    
    ")
        fmt.Println("trimright:", result)
    
        split_result := strings.Fields(str)
        for i := 0; i < len(split_result); i++ {
            fmt.Println(split_result[i])
        }
    
        split_result = strings.Split(str, "l")
        for i := 0; i < len(split_result); i++ {
            fmt.Println(split_result[i])
        }
    
        str2 := strings.Join(split_result, "l")
        fmt.Println("join:", str2)
    
        str2 = strconv.Itoa(1000)
        fmt.Println("Itoa:", str2)
    
        num, err := strconv.Atoi(str2)
        if err != nil {
            fmt.Println("can not convert str to int", err)
        }
        fmt.Println("number is:", num)
    }
    练习二

    二、时间和日期类型

    • 1. time包
    • 2. time.Time类型,用来表示时间
    • 3. 获取当前时间,now := time.Now()
    • 4. time.Now().Day(),time.Now().Minute(),time.Now().Month(),time.Now().Year()
    • 5. 格式化,fmt.Printf(“%02d/%02d%02d %02d:%02d:%02d”, now.Year()…)
    • 6. time.Duration用来表示纳秒
    • 7. 一些常量:
    const (
    Nanosecond Duration = 1
    Microsecond = 1000 * Nanosecond
    Millisecond = 1000 * Microsecond
    Second = 1000 * Millisecond
    Minute = 60 * Second
    Hour = 60 * Minute
    )
    • 8. 格式化:
    now := time.Now()
    fmt.Println(now.Format(“02/1/2006 15:04”))
    fmt.Println(now.Format(“2006/1/02 15:04”))
    fmt.Println(now.Format(“2006/1/02"))

    练习:写一个程序,获取当前时间,并格式化成 2017/06/15 08:05:00形式, 统计一段代码的执行耗时,单位精确到微秒。

    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    func test() {
    	time.Sleep(time.Millisecond * 100)
    }
    
    func main() {
    	now := time.Now()
    	fmt.Println(now.Format("2006/01/02 15:04:05"))
    	start := time.Now().UnixNano() // 1970年到现在的纳秒数
    	test()
    	end := time.Now().UnixNano()
    
    	fmt.Println("cost:%d us
    ", (end-start)/1000)
    }

    三、指针类型

    • 1. 普通类型,变量存的就是值,也叫值类型

    • 2. 获取变量的地址,用&,比如: var a int, 获取a的地址:&a

    • 3. 指针类型,变量存的是一个地址,这个地址存的才是值

    • 4. 获取指针类型所指向的值,使用:*,比如:var *p int, 使用*p获取p指向的值

    练习:写一个程序,获取一个变量的地址,并打印到终端,写一个函数,传入一个int类型的指针,并在函数中修改所指向的值。在main函数中调用这个函数,并把修改前后的值打印到终端,观察结果

    package main
    
    import "fmt"
    
    func modify(n *int) {
    	fmt.Println(n)
    	*n = 10000000
    	return
    }
    
    func main() {
    	var a int = 10  // 整数类型
    	fmt.Println(&a) // 取地址
    	fmt.Println(a)  // 取变量值
    
    	var p *int // 指针类型
    	p = &a
    	fmt.Println(p)  // 取地址
    	fmt.Println(*p) // 取指针指向的变量值
    	*p = 100        // 修改指针地址指向的变量值
    	fmt.Println(a)  // 响应的a的变量值也更改
    
    	var b int = 999
    	p = &b
    	*p = 5
    
    	fmt.Println(a)
    	fmt.Println(b)
    
    	modify(&a)
    	fmt.Println(a)
    }

    四、流程控制

    1. if / else 分支判断

    方式一:
    if condition1 {
    }
    
    方式二:
    if condition1 {
        
    } else {
    
    方式三:
    }
    if condition1 {
        
    } else if condition2 {
    
    } else if condition3 {
    } else {
    }
    
    方式四:
    if condition1 {
        
    }
    else {
    
    }

     例子

    package main
    import “fmt”
    func main() {
        bool1 := true
        if bool1 {
            fmt.Printf(“The value is true
    ”)
        } else {
            fmt.Printf(“The value is false
    ”)
        }
    }
    


    练习:写一个程序,从终端读取输入,并转成整数,如果转成整数出错,则输出 “can not convert to int”,并返回。否则输出该整数。

    package main
    
    import (
    	"fmt"
    	"strconv"
    )
    
    func main() {
    	var str string
    	fmt.Printf("请输入一个字符串:")
    	fmt.Scanf("%s", &str)
    
    	number, err := strconv.Atoi(str)
    	if err != nil {
    		fmt.Println("convert failed, err:", err)
    		return
    	}
    	fmt.Println(number)
    }

    2. switch case语句

    语法

    switch var {
    	case var1:
    	case var2:
    	case var3:
    	default:
    	}
    

     写法

    写法一
    	var i = 0
    	switch i {
    	case 0:
    	case 1:
    		  fmt.Println(“1”)
    	case 2:
    	fmt.Println(“2”)
    	default:
    		 fmt.Println(“def”)
    	}
    
    写法二
    	var i = 0
    	switch i {
    	case 0:
    			fallthrough
    	case 1:
    		  fmt.Println(“1”)
    	case 2:
    	fmt.Println(“2”)
    	default:
    		 fmt.Println(“def”)
    	}
    
    写法三
    	var i = 0
    	switch i {
    	case 0, 1:
    		  fmt.Println(“1”)
    	case 2:
    	fmt.Println(“2”)
    	default:
    		 fmt.Println(“def”)
    	}
    写法四
    	var i = 0
    	switch {
    	condition1:
    		  fmt.Println(“i > 0 and i < 10”)
    	condition2:
    	fmt.Println(“i > 10 and i < 20”)
    	default:
    		 fmt.Println(“def”)
    	}
    	
    	var i = 0
    	switch {
    	case i > 0 && i < 10:
    		  fmt.Println(“i > 0 and i < 10”)
    	case i > 10 && i < 20:
    	fmt.Println(“i > 10 and i < 20”)
    	default:
    		 fmt.Println(“def”)
    	}
    写法五
    	switch i := 0 {
    	case i > 0 && i < 10:
    		  fmt.Println(“i > 0 and i < 10”)
    	case i > 10 && i < 20:
    	fmt.Println(“i > 10 and i < 20”)
    	default:
    		 fmt.Println(“def”)
    	}
    

    练习:猜数字,写一个程序,随机生成一个0到100的整数n,然后用户在终端,输入数字,如果和n相等,则提示用户猜对了。如果不相等,则提示用户,大于或小于n。

    package main
    
    import (
    	"fmt"
    	"math/rand"
    )
    
    func main() {
    	var n int
    	n = rand.Intn(100)
    	fmt.Println(n)
    	for {
    		var input int
    		fmt.Printf("请输入一个0-100的整数:")
    		fmt.Scanf("%d
    ", &input)
    		flag := false
    		switch {
    		case input == n:
    			flag = true
    			fmt.Println("you are right")
    		case input < n:
    			fmt.Printf("%d is smaller
    ", input)
    		case input > n:
    			fmt.Printf("%d is bigger
    ", input)
    		}
    		if flag {
    			break
    		}
    	}
    }

    3. for 语句

    写法1

    for 初始化语句; 条件判断; 变量修改 {
    }
    
    for i := 0 ; i < 100; i++ {
    fmt.Printf(“i=%d
    ”, i)
    }
    

    练习:写一个程序,在终端打印如下图形
    A
    AA
    AAA
    AAAA
    AAAAA

    package main
    
    import "fmt"
    
    func Print(n int) {
    	for i := 1; i <= n; i++ {
    		for j := 0; j < i; j++ {
    			fmt.Printf("A")
    		}
    		fmt.Println()
    	}
    }
    
    func main() {
    	Print(6)
    }
    

    写法二

    for  条件 {
    }
    
    for i > 0 {
          fmt.Println(“i > 0”)
    }
    
    for true {
          fmt.Println(“i > 0”)
    }
    
    for {
          fmt.Println(“i > 0”)
    }

     写法三 for range语句

    str := “hello world,中国”
    for i, v := range str {
         fmt.Printf(“index[%d] val[%c] len[%d]
    ”, i, v, len([]byte(v)))
    }
    

     用来遍历数组、slice、map、chan

    写法四  break,coutinue语句

    str := “hello world,中国”
    for i, v := range str {
           if i > 2 {
                 continue
           }
      if (i > 3) {
             break  }
         fmt.Printf(“index[%d] val[%c] len[%d]
    ”, i, v, len([]byte(v)))
    }
    

     4. goto和label语句

    package main
    import "fmt"
    func main() {
    LABEL1:
    	for i := 0; i <= 5; i++ {
    		for j := 0; j <= 5; j++ {
    			if j == 4 {
    				continue LABEL1
    			}
    			fmt.Printf("i is: %d, and j is: %d
    ", i, j)
    		}
    	}
    }
    
    
    package main
    
    func main() {
    	i := 0
    HERE:
    	print(i)
    	i++
    	if i == 5 {
    		return
    	}
    	goto HERE
    }

    五、函数

    1. 语法

    声明语法:func 函数名 (参数列表) [(返回值列表)] {}
    

    2. golang 函数特点

    • a. 不支持重载,一个包不能有两个名字一样的函数

    • b. 函数是一等公民,函数也是一种类型,一个函数可以赋值给变量

    • c. 匿名函数

    • d. 多返回值

     例

    package main
    
    import "fmt"
    
    func add(a, b int) int {
    	return a + b
    }
    
    func test() {
    	return
    }
    
    func main() {
    	c := add
    	sum := c(200, 300)
    	fmt.Println(sum)
    
    	str := "hello world,中国"
    	for index, val := range str {
    		fmt.Printf("index[%d] val[%c] len[%d]
    ", index, val, len([]byte(string(val))))
    	}
    }

     例2

    package main
    
    import "fmt"
    
    type op_func func(int, int) int
    
    func add(a, b int) int {
    	return a + b
    }
    
    func sub(a, b int) int {
    	return a - b
    }
    
    func operator(op func(int, int) int, a, b int) int {
    	return op(a, b)
    }
    
    func main() {
    	var c op_func
    	c = add
    	// c := add
    
    	sum := operator(c, 100, 200)
    	dif := operator(sub, 100, 200)
    
    	fmt.Println(sum)
    	fmt.Println(dif)
    }
    

    3. 函数传参的两种方式

      1). 值传递

      2) 引用传递

    注意1:无论是值传递,还是引用传递,传递给函数的都是变量的副本,不过,值传递是值的拷贝。引用传递是地址的拷贝,一般来说,地址拷贝更为高效。而值拷贝取决于拷贝的对象大小,对象越大,则性能越低。
    注意2:map、slice、chan、指针、interface默认以引用的方式传递

    package main
    
    import "fmt"
    
    func modify(a int) {
    	a = 100
    }
    
    func main() {
    	a := 8
    	fmt.Println(a)
    	modify(a)
    	fmt.Println(a)
    }
    

    4. 命名返回值的名字

    func add(a, b int) (c int) {
            c = a + b
            return
    }
    
    func calc(a, b int) (sum int, avg int) {
            sum = a + b
            avg = (a +b)/2
            return
    }
    

    5. _标识符,用来忽略返回值

    func calc(a, b int) (sum int, avg int) {
            sum = a + b
            avg = (a +b)/2
            return}
    func main() {
          sum, _ := calc(100, 200)
    }
    

    6. 可变参数

    注意:其中arg是一个slice,我们可以通过arg[index]依次访问所有参数,通过len(arg)来判断传递参数的个数

    练习:写一个函数add,支持1个或多个int相加,并返回相加结果, 写一个函数concat,支持1个或多个string相拼接,并返回结果

    package main
    
    import "fmt"
    
    func add(a int, arg ...int) int {
    	var sum int = a
    	for i := 0; i < len(arg); i++ {
    		sum += arg[i]
    	}
    	return sum
    }
    
    func concat(a string, arg ...string) (result string) {
    	result = a
    	for i := 0; i < len(arg); i++ {
    		result += arg[i]
    	}
    	return
    }
    
    func main() {
    	sum := add(10, 3, 5, 6, 6)
    	fmt.Println(sum)
    
    	res := concat("hello", " ", "world")
    	fmt.Println(res)
    }
    

    7. defer用途

    • 1). 当函数返回时,执行defer语句。因此,可以用来做资源清理
    • 2). 多个defer语句,按先进后出的方式执行
    • 3). defer语句中的变量,在defer声明时就决定了。

     关闭文件句柄

    func read() {
    file := open(filename)
    defer file.Close()
    
    //文件操作
    }  

    锁资源释放

    func read() {
    mc.Lock()
    defer mc.Unlock()
    //其他操作
    }

    数据库连接释放

    func read() {
    conn := openDatabase()
    defer conn.Close()
    //其他操作
    }

    defer示例

    package main
    
    import "fmt"
    
    var (
        result = func(a1 int, b1 int) int {
            return a1 + b1
        }
    )
    
    func test(a, b int) int {
        result := func(a1 int, b1 int) int {
            return a1 + b1
        }(a, b)
        return result
    }
    
    func main() {
        fmt.Println(test(100, 200))
        fmt.Println(result(100, 200))
    
        var i int = 0
        // defer语句编译的时候会把语句放入栈中,函数结尾的时候一个一个出栈执行
        defer fmt.Println(i)
        defer fmt.Println("second")
    
        i = 10
        fmt.Println(i)
    }
    defer示例

    本节作业

    • 1. 编写程序,在终端输出九九乘法表。

    • 2. 一个数如果恰好等于它的因子之和,这个数就称为“完数”。例如6=1+2+3.编程找出1000以内的所有完数。

    • 3. 输入一个字符串,判断其是否为回文。回文字符串是指从左到右读和从右到左读完全相同的字符串。

    • 4. 输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。

    • 5. 计算两个大数相加的和,这两个大数会超过int64的表示范围.

    参考

    package main
    
    import "fmt"
    
    func multi() {
        for i := 1; i < 10; i++ {
            for j := 1; j <= i; j++ {
                fmt.Printf("%d*%d=%d	", i, j, i*j)
            }
            fmt.Println()
        }
    }
    
    func main() {
        multi()
    }
    作业一
    package main
    
    import "fmt"
    
    func perfect(n int) bool {
        var sum int = 0
        for i := 1; i < n; i++ {
            if n%i == 0 {
                sum += i
            }
        }
        return sum == n
    }
    
    func process(n int) {
        var flag bool = false
        for i := 1; i < n+1; i++ {
            if perfect(i) {
                flag = true
                fmt.Println(i, "是完数")
            }
        }
        if flag == false {
            fmt.Println(n, "以内没有完数")
        }
    }
    
    func main() {
        var n int
        fmt.Printf("请输入一个数字:")
        fmt.Scanf("%d", &n)
        process(n)
    }
    作业二
    package main
    
    import "fmt"
    
    func process(str string) bool {
        // rune代表一个字符(中文英文都可以)
        // byte代表一个字节,一个中文字符代表三个字节
        t := []rune(str)
        length := len(t)
        for i, _ := range t {
            if i == length/2 {
                break
            }
            last := length - i - 1
            if t[i] != t[last] {
                return false
            }
        }
        return true
    }
    
    func main() {
        var str string
        fmt.Printf("请输入一个字符串:")
        fmt.Scanf("%s", &str)
        if process(str) {
            fmt.Println(str, "是回文: yes")
        } else {
            fmt.Println(str, "是回文: no")
        }
    }
    作业三
    package main
    
    import (
        "bufio"
        "fmt"
        "os"
    )
    
    func process(str string) (word_count int, sapce_counr int, number_count int, other_count int) {
        t := []rune(str)
        for _, v := range t {
            switch {
            case v >= 'a' && v <= 'z':
                fallthrough
            case v >= 'A' && v <= 'Z':
                word_count++
            case v == ' ':
                sapce_counr++
            case v >= '0' && v <= '9':
                number_count++
            default:
                other_count++
            }
        }
        return
    }
    
    func main() {
        fmt.Printf("请输入一个字符串:")
        reader := bufio.NewReader(os.Stdin)
        result, _, err := reader.ReadLine()
        if err != nil {
            fmt.Println("read from console err", err)
            return
        }
        wc, sc, nc, oc := process(string(result))
        fmt.Printf("word_count:%d
    space_count:%d
    number_count:%d
    other_count:%d", wc, sc, nc, oc)
    
    }
    作业四
    package main
    
    import (
        "bufio"
        "fmt"
        "os"
        "strings"
    )
    
    func multi(str1, str2 string) (result string) {
        if len(str1) == 0 && len(str2) == 0 {
            result = "0"
            return
        }
    
        var index1 = len(str1) - 1
        var index2 = len(str2) - 1
        var left int
    
        for index1 >= 0 && index2 >= 0 {
            c1 := str1[index1] - '0'
            c2 := str2[index2] - '0'
    
            sum := int(c1) + int(c2) + left
            if sum >= 10 {
                left = 1
            } else {
                left = 0
            }
            c3 := (sum % 10) + '0'
            result = fmt.Sprintf("%c%s", c3, result)
            index1--
            index2--
        }
        for index1 >= 0 {
            c1 := str1[index1] - '0'
            sum := int(c1) + left
            if sum >= 10 {
                left = 1
            } else {
                left = 0
            }
            c3 := (sum % 10) + '0'
            result = fmt.Sprintf("%c%s", c3, result)
            index1--
        }
        for index2 >= 0 {
            c1 := str2[index2] - '0'
            sum := int(c1) + left
            if sum >= 10 {
                left = 1
            } else {
                left = 0
            }
            c3 := (sum % 10) + '0'
            result = fmt.Sprintf("%c%s", c3, result)
            index2--
        }
        if left == 1 {
            result = fmt.Sprintf("1%s", result)
        }
        return
    }
    
    func main() {
        fmt.Printf("请输入一个字符串:")
        reader := bufio.NewReader(os.Stdin)
        result, _, err := reader.ReadLine()
        if err != nil {
            fmt.Println("read from console err", err)
            return
        }
        strSlice := strings.Split(string(result), "+")
        if len(strSlice) != 2 {
            fmt.Println("please input a+b")
            return
        }
        strNumber1 := strings.TrimSpace(strSlice[0])
        strNumber2 := strings.TrimSpace(strSlice[1])
        fmt.Println(multi(strNumber1, strNumber2))
    }
    作业五
  • 相关阅读:
    学习进度博客六
    Ultimate四则运算
    水骑士团队介绍
    返回一个二维整数数组中最大联通子数组的和
    学习进度博客五
    构建之法阅读笔记02
    四则运算4
    敏捷开发方法综述
    第一冲刺阶段站立会议02
    学习进度表_七周
  • 原文地址:https://www.cnblogs.com/zhangyafei/p/10657486.html
Copyright © 2011-2022 走看看