字符串,时间,流程控制,函数

  • strings和strconv的使用
  • Go中时间和日期类型
  • 流程控制
  • 函数详解

一、strings和strconv的使用

strings常用方法

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

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

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

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

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

strings.Count(str string,count int)string: 字符串计数

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

strings.ToLower(str string) 转换为小写

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

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

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

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

strings.TrimRight(str string,cunt string): 去掉字符串尾部cut字符

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

string.Split(str string,split string): 返回str split分割的所有子串的slice

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

strconv常用方法

strconv.Itoa(i int): 把一个整数转换成字符串

strconv.Atio(str string)(int,errror): 把一个字符串转换成整数

二、Go中时间和日期类型

换算知识:

1s=1000ms=1000000微秒=1000000000纳秒=1000000000000皮秒=10^15飞秒=10^18啊秒=10^21仄秒=10^24幺秒 1s=10^3ms(毫秒)=10^6μs(微秒)=10^9ns(纳秒)=10^12ps(皮秒)=10^15fs(飞秒)=10^18as(阿秒)=10^21zm(仄秒)=10^24ym(幺秒)

当前时间:now:= time.Now()

time.Now().Day() time.Now().Minute() time.Now().Month() time.Now().Year() time.Duration用来表示纳秒

一些常用的时间常量

const ( Nanosecond Duration = 1 Microsecond =1000 * Nanosecond //纳秒 Millisecond =1000 * Microsecond //微秒 Second =1000 * Millisecond //毫秒 Minute =60 * Second // 秒 Hour =60 * Minute //分钟 )

时间格式化

package main

import (
    "fmt"
    "time"
)

func main() {
    now := time.Now()
    fmt.Println(now.Format("2006/01/02 15:04:05"))   //layout必须为 "2006-01-02 15:04:05"
}

小练习:

统计一段代码的执行耗时,单位精确到微秒

package main

import (
    "fmt"
    "time"
)

func test() {
    time.Sleep(time.Millisecond * 1000)
}

func main() {
    now := time.Now()
    fmt.Println(now.Format("2006/01/02 15:04:05"))

    start := time.Now().UnixNano()
    test()
    end := time.Now().UnixNano()

    fmt.Printf("cost:%d us\n", (end-start)/1000)
}

三、指针类型

普通的类型,变量存的就是值,也叫值类型 获取变量的地址,用&, 指针类型,变量存的是一个地址,这个地址存的才是真正的值 获取指针类型所指向的值,用*,例如:var *p int, 使用 *p获取p指向值 通过下面的代码例子理解:

package main

import "fmt"

func main() {
    var a int = 10
    //通过&a打印a的指针地址
    fmt.Println(&a)
    //定义一个指针类型的变量p
    var p *int
    //a的指针地址复制给p
    p = &a
    fmt.Println(*p)
    //给指针p赋值
    *p = 100
    fmt.Println(a)
}

四、流程控制

if else 分支判断

常见格式类型如下:

if 条件{
}
if 条件{
}else{
}
if 条件{
}else if 条件{
}else{
}

switch case

例一:

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

例二: 如果满足了var1 想要穿透下一个需要添加fallthrough

package main
import "fmt"
func main() {
    var a int = 0
    switch a {
    case 0:
        fmt.Println("a 等于0")
        fallthrough
    case 1:
        fmt.Println("a等于1")
    default:
        fmt.Println("a等于默认值")
    }
}

如果我们没有添加fallthrough只会打印a等于0,但是现在回把case1中的打印内容也打印出来 同样这里我们需要知道case 后面是可以写条件的

例三:

package main

import (
    "fmt"
)

func main() {
    var a int = 21
    switch{
    case a > 0 && a < 10:
        fmt.Println("a > 5 && a < 10")
    case a > 10 && a < 20:
        fmt.Println("a > 10 && a < 20")
    case a > 20 && a < 30:
        fmt.Println("a > 20 && a < 30")
    default:
        fmt.Println("0")
    }
}

for语句

语法 for 初始化变量;条件判断;变量修改{ } 一个简单的例子

for i:=0;i<100;i++{
    fmt.Println(i)
}

for循环的其他几种常见写法 for 条件 { } 死循环的写法 for { }

for range语句

通过一个例子理解:

str := "hello 世界"
for i,v := range str{
    fmt.Printf("index[%d] val[%c] len[%d]\n",i,v,len([]byte(string(v))))
}

这里需要注意的一个问题是,range str返回的是两个值,一个是字符串的下标,一个是字符串中单个的字符

➜ GoWorks go run src/go_learning/day3/for/example1/main.go
index[0] val[h] len[1]
index[1] val[e] len[1]
index[2] val[l] len[1]
index[3] val[l] len[1]
index[4] val[o] len[1]
index[5] val[ ] len[1]
index[6] val[世] len[3]
index[9] val[界] len[3]

lable

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\n",i,j)
}
}
}

代码中我们在continue 后面添加了一个LABEL1这样当循环匹配到j等于4的时候,就会跳出循环,重新回到最外成i的循环,而如果没有LABEL1则就会跳出j的本次循环,执行j++进入到j的下次循环

goto(代码中我们不建议使用goto)

package main

import "fmt"

func main() {
/* 定义局部变量 */
var a int = 10

/* 循环 */
LABEL1: for a < 20 {
if a == 15 {
/* 跳过迭代 */
a = a + 1
goto LABEL1
}
fmt.Printf("a的值为 : %d\n", a)
a++
}
}

break 和 continue

一句话解释:break是终止整个循环,continue是终止此次循环

五、函数

1、声明语法

func 函数名 (参数列表) [(返回列表)]{ } 一些常见的写法例子

func add(){
}
func add(a int,b int){
}
func add(a int,b int) int {
}
func add(a int,b int) (int,int) {
}
func add(a,b int)(int,int){
}

go函数的特点

  1. 不支持重载,一个包不能包含连个名字一样的函数
  2. 函数是一等公民,函数也是一种类型,一个函数可以赋值给变量
  3. 匿名函数
  4. 多返回值

通过以下例子演示第2个特点:

package main

import (
    "fmt"
)

type op_func func(int,int) int

func add(a,b int) int {
    return a + b
}

func operator(op op_func,a,b int) int{
    return op(a,b)
}

func main() {
    c := add
    sum := operator(c,100,200)
    fmt.Println(sum)
}

函数参数传递方式

值传递和引用传递

无论是值传递还是引用传递,传递给函数的都是变量的副本,不过值传递的是值的拷贝,引用传递是传递的地址的拷贝,一般来说,地址拷贝更为高效,而值拷贝取决于拷贝的对象的大小,对象越大,则性能越低

命名返回值的名字

func add_sum(a,b int)(c int){
    c = a + b
    return 
}

可变参数

表示0个或多个参数

func add(arg ...int) int {
}

表示1个或多个参数

func add(a int,arg ...int) int {
}

其中arg是一个slice,我们可以通过arg[index]获取参数 通过len(arg)可以判断参数的个数

defer用途

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

通过以下例子理解:

package main
import "fmt"
func main() {
    a := 0
    defer fmt.Println("defer---->", a)
    a++
    fmt.Println(a)
}

结果为:

1
defer----> 0

Search

    Table of Contents