一、本篇内容

1、string和strconv使用

2、go中的时间和日期类型

3、流程控制

4、函数讲解

二、string和strconv使用

1、  string.HasPrefix(s tring ,prefix string)bool,判断字符串s是否是prefix开头

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

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

练习

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)
}
return path
} func main(){
var (
url string
path string
) fmt.Scanf("%s%s",&url,&path)//终端输入
url=urlprocess(url)
path=pathprocess(path) fmt.Println(url)
fmt.Println(path) }
执行:
D:\project>go build -o day3/example1.exe go_dev/day3/example/example1 D:\project>cd day3 D:\project\day3>example1.exe
10.100.8.8/user/login c:/study
http://10.100.8.8/user/login
c:/study/

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

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

练习3:写一个函数返回一个字符串在另一个字符串的首次出现和最后出现的位置

func strIndex(str string,substr string)(int,int){}

3、  strings.Replace(str string,old string,new string,n int)字符串替换。str是原生的字符串,old要替换的字符串,new是新的字符串,n为替换的次数

如:”hehello” ,“he” ,“rr” ,1   结果为:”rrhello”  如果全部替换,那么n为-1或者0

4、  strings.Count(str string,substr string)int 字符串计数

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

6、  strings.ToLower(str string)string 转为小写

7、  string ToUpper(str string)string:转为大写

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

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

如:strings.TrimSpace(“  sk  ”) 结果为sk

11、strings.Trim(str string,cut string):去掉字符串两边cut字符

如:

strings.Trim(“abbacba”,”ab”)结果

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

13、strings.TrimRight(str string,cut string):去掉字符串末尾cut字符

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

如:strings.Field(“abc d  e”)  结果为[“abc”,”d”,”e”]

15、strings.Split(str string,split string)返回str split分隔的所有字串slice

如:

strings.Split(“a,b,c”)  [“a”,”b”,”c”]

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

17、strconv.Itoa(i int) 把一个整数i转化为字符串。还可以用fmt的方式格式化转为字符串

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

package main

import (
"strings"
"fmt"
"strconv"
) func main(){
str:="hello world abc \n"
result:=strings.Replace(str,"world","you",)
fmt.Println("replace",result) count:=strings.Count(str,"")
fmt.Println("count",count) result=strings.Repeat(str,)
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,"\n\r")
fmt.Println("trim",result) result=strings.TrimLeft(str,"\n\r")
fmt.Println("trimleft",result) result=strings.TrimRight(str,"\n\r")
fmt.Println("trimright",result) splitResult:=strings.Fields(str)
for i:=;i<len(splitResult);i++{
fmt.Println("fields",splitResult[i])
} splitResult=strings.Split(str,"l")
for i:=;i<len(splitResult);i++{
fmt.Println("split",splitResult[i])
} str2:=strings.Join(splitResult,"l")
fmt.Println("join",str2) str2=strconv.Itoa()
fmt.Println("itoa",str2) number,err:=strconv.Atoi(str2)
if err!=nil{
fmt.Println("can not conert to int",err)
}
fmt.Println(number) }
执行结果:
D:\project>go build go_dev/day3/example/example2 D:\project>example2.exe
replace hello you abc count
repeat hello world abc
hello world abc
hello world abc tolower hello world abc toupper HELLO WORLD ABC trimspace hello world abc
trim hello world abc
trimleft hello world abc trimright hello world abc
fields hello
fields world
fields abc
split he
split
split o wor
split d abc join hello world abc itoa

三、时间和日期类型

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.Duratime用来表示纳秒

7、  一些常量:

const(
Nanosecond Duration=1 //纳秒
Microsecond =1000*Nanosecond //微妙
Milisecond =1000*Microsecond //毫秒
second =1000*Milisecond
Minute =60*second
Hour =60*Minute
)

8、  格式化

now :=time.Now()
fmt.Printf(now.Format(“02/1/2006 15:04”))
fmt.Printf(now.Format(“2006/1/02 15:04”))
fmt.Printf(now.Format(“2006/1/02”))

练习:

写一个程序,获取当前时间,并且格式化为 2017/06/15 08:05:00形式

写一个程序,统计一段代码的耗时操作,单位精确到微妙

package main

import (
"time"
"fmt"
) func test(){
time.Sleep(time.Millisecond*)
} 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.Printf("cost:%d us\n",(end-start)/) //统计时间
}
/*
D:\project>go build go_dev/day3/example/example3 D:\project>example3.exe
2017/11/24 16:49:38
*/

四、指针类型:

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

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

3、  指针类型,变量保存的是一个地址,这个地址所指向的才是值

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

取地址前面加&,获取值前面加上* ,上面图,地址就相当于中介

1、  指针变量怎么去声明

2、  指针赋值应该赋值的是一个地址

3、  用*p这种变量前面加*去取指针所指的值

练习:

写一个程序,获取一个变量的地址,并且打印到终端

package main

import "fmt"

func main(){
var a int=
fmt.Println(&a) var p *int
p=&a
fmt.Println(*p)
*p=
fmt.Println(a) //这里的a的值为100 var b int=
p=&b
*p=
fmt.Println(a) //
fmt.Println(b) // }

解析:

上面p是一个指针,然后这个指针赋值,指向了a的地址,然后让指针的值等于100,这个时候也就是改变了a的地址,也就是a的值为100

然后下面p这个指针指向了b的地址,然后把指针的值设置为5,这个时候b的值就改变了变成了5,原因是指针就是b的地址,b的值变成了5.但是a的值不变,因为此时指针对应的是b而不是a

巧记:

如果给指针赋值地址,就把指针当作赋值的地址,然后给*p赋值,也就是相当于给这个地址复制

其实指针就是一个地址

写一个函数输入一个int类型的指针,并在函数中修改所指向的值,在main函数中调用这个函数,并把修改前后的值打印到终端,观察结果

package main

import "fmt"

func modify(p * int){
fmt.Println(p) //打印的是一个地址
*p=
return
} func main(){
var a int=
fmt.Println(&a) var p *int
p=&a
fmt.Println(*p)
*p=
fmt.Println(a) //这里的a的值为100
modify(&a) //因为参数是指针,所以这里传入的应该是地址
fmt.Println(a)//
}
上面第一个函数的参数是指针,所以传入参数的时候应该传入的是一个地址(指针就是一个地址),然后在函数中进行给指针赋值,也就是给地址赋值所以a的值就变化了

流程控制

1、  if/else

注意这里的else必须是上一个语句块的最后位置

写一个程序,从终端输入一个整数,如果不是整数就报错

package main

import (
"fmt"
"strconv"
) func main(){
var str string
fmt.Scanf("%s",&str) //这里是获取输入内容的地址
number,err:=strconv.Atoi(str)
if err!=nil{
fmt.Println("converf failed",err)
return
}
fmt.Println(number)
}

2、  swich case语句

语法:

swich var {      //这里第一行是变量

case var1:

case var2:

case var3:

default:

}

写法二、多个条件可以写到一行里面

上面的一个case执行完毕之后,这个流程就结束了,如果想要执行下一个case,需要在case下面写上fallthrough

如:

package main

import "fmt"

func main(){
var a int=10 switch a{
case 0:
fmt.Print("a is equal 0")
case 10:
fmt.Println("a is equal 10")
default:
fmt.Println("a is equal default")
}
}
方法二、
package main import "fmt" func main(){
var a int=10 switch a{
case 0,1,2,3,4:
fmt.Print("a is equal 0")
case 10:
fmt.Println("a is equal 10")
default:
fmt.Println("a is equal default")
}
}
switch的条件判断写法
var i =0
switch {
condition1: //条件语句块
fmt.Println(“i>0 and i<10”)
condition2:
fmt.Println(“i>10 and i<20”)
default:
fmt.Println(“default”)
}
或者
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(“default”)
}
或者
switch i:=1;{
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(“default”)
}

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

package main

import(
"fmt"
"math/rand"
) func main(){
var n int
n=rand.Intn()
for {
var input int
/*
下面如果不加上\n的话会输出两次,原因是输入的数字和回车会放入到缓冲区,然后scanf
过来取,首先取输入的数字,然后取回车键,分别打印。
这里的Scanf默认是空格来分割的,这里用\n来分割,就不会打印输出两次了
*/
fmt.Scanf("%d\n",&input)
flag:=false
switch {
case input==n:
fmt.Println("you are right")
flag=true
case input>n:
fmt.Println("bigger")
case input<n:
fmt.Println("less")
}
if flag{
break
}
}
}

for循环

for 初始化;条件判断;变量修改

用法1、

for i=0;i<len(a);i++{

}

外层控制行数,内层控制数量

package main

import(
"fmt"
) func print(n int){
for i:=;i<n+;i++{
for j:=;j<i;j++{
fmt.Printf("A")
}
fmt.Println() //这里代表换行
}
} func main(){
print()
}

2、

for 条件{

}

如:

for i>0{

fmt.Println(“i>0”)

}

for true{   //无限循环

fmt.Println(“i>0”)

}

for{        //死循环

fmt.Println(“i>0”)

}

3、  for range语句

str :=”hello world ,中国”

for i,v :=range str{   //i是下标。v是下标对应的值。这里的i和v是没有声明的所以需要:=

fmt.Printf(“index[%d] val[%e] len[%d]\n”,i,v,len([]byte(v)))

}

用来遍历 slice、map、chan

4、

str:=”hello world,中国”

for i,v:=range str{

if i>2{

continue

}

if i>3{

break

}

fmt.Println(“index[%d],val[%c] len[%d]”,i,v,len([] byte(string(v))))//这里因为底层是byte,所以这里把长度转化字符串,然后再转换成字节

}

goto和label   HERE语句

首先定义一个label标识,可以跳到这个标识的位置

如:
package main
import (
“fmt”
)
func main(){
LABEL:
for i:=;i<=;i++{
for j:=;j<=;j++{
if j=={
countinue LABEL //当j等于4的时候就跳到LABEL上面
}
fmt.Printf(“i is %d j is :%d/n”,i,j)
}
}
}

goto,只能在一个函数中跳转,实现一个for循环

package main
func main(){
i:=0
HERE: //这里的HERE是一个标识
print(i)
i++
if i==5{
return
}
goto HERE
}
小练习:
for i:=0;i<7;i++{
if i%2==0{
continue
}
fmt.Println(i)
}
结果为1 3 5

 函数

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

func add(){}

func add(a int ,bint){}

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

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

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

2、  golang函数特点:

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

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

c)         支持匿名函数

d)         支持多返回值

3、  golang函数的特点

1、package main

import(
"fmt"
) func add(a,b int) int{
return a+b
} func main(){
c:=add //可以赋值给一个变量,这里的c就相当于指针(地址)
fmt.Println(c) sum:=c(10,20) //因为地址已经赋值,所以这里可以进行运算
fmt.Println(sum) } 2、
type是定义一种类型 后面是类型名字,第三个才是一种类型
package main import (
"fmt"
) type add_func func(int,int) int //这个定义一个类型名字是add_func 类型是一个函数
func add(a,b int) int{
return a+b
} func operator(op add_func,a int,b int) int{//这里的op是函数类型
return a+b
} func main(){
var c add_func
c=add
fmt.Println(c)
sum:=operator(c,100,200) //注意这里的c也就是add要和op的类型是一样,不然会出错
fmt.Println(sum)
}

  

函数参数传递的方式

值传递

引用传递

注意点:

1、无论是值传递还是引用传递,传递给函数的都是变量的副本,不过,值传递是值的拷贝。引用传递是地址的拷贝,一般来说,地址拷贝更为高效,而值拷贝取决于拷贝的对象大小,对象越大,则性能越低  (地址64位最长为8个字节)

2、拷贝如果是一个变量,会拷贝变量所占的内存数量,不会去判断是值类型还是引用类型

3、map,slice,chan、指针、interface默认传递的是引用

4、基本的数据类型都是值传递,结构体也是值传递,如int

下面程序结果
package main
import “fmt”
func modify(a int){
a=100
}
func main(){
a:=8
fmt.Println(a) //8
modify(a)
fmt.Println(a) //8
}
上面为什么结果没变呢?
解析:
原因是这里的a是值传递,然后在modify这个是值传递,然后里面修改的只是副本,如果想修改必须是把值传递变成引用传递

package main

import(
   "fmt"
)

func modify(a *int){
   *a=100
}

func main(){
   a:=8
   fmt.Println(a)
   modify(&a)
   fmt.Println(a)
}

结果:

//8

//100

  

命名返回值的名字

func add(a,b int)(c int){
c=a+b
return
}
上面的c可以直接用,然后这样return的时候就不用在return后面写上c了
如:
func calc(a,b int)(sum int,avg int){
sum=a+b
avg=(a+b)/2
return
}
上面就是给返回值命名

  

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

func calc(a,b int) (sum int,avg int){
sum=a+b
avg=(a+b)/
return
}
func main(){
sum,_=calc(,)
}
上面的这个小程序如果只想要和不想要平均值,那么这个时候可以用_来忽略返回值

可变参数

func add(arg```int) int{   //0个或者多个参数
}
func add(a int,arg```int)int{ //1个或者多个参数
}
func add(a int,b int,arg```int) int{ //2个或者多个参数
}
注意:其中arg是一个slice,我们可以通过arg[index]依次访问所有参数,通过len(arg)来判断传递参数的个数

 

练习:

1、  写一个函数add,支持一个或者多个int相加,并且返回相加结果

 

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 main(){
sum:=add(10)
fmt.Println(sum)
} 2、 写一个函数concat,支持一个或者多个string相拼接,并返回结果 package main import (
"fmt"
) func concat(a string,arg...string)(result string){
result=a //这个是如果arg没有值,就让返回值等于第一个参数
for i:=0;i<len(arg);i++{
result+=arg[i]
}
return
} func main(){
res:=concat("hello"," ","world")
fmt.Println(res)
}
6、

defer的用途

1、当函数返回的时候执行defer语句,因此,可以用来做资源清理

2、多个defer语句,按照先进后出的方式执行

1、  defer语句中的变量,在defer声明时就决定了

package main

import (
"fmt"
) func main(){
var i int=0
//下面传入的i也就是传入参数进去,这里的参数就是一个副本
//执行的时候会把defer压到一个栈里面,等程序执行完毕之后执行这个defer
defer fmt.Println(i) //defer后面相当于执行一个函数调用,这里取的定义的i的值也就是0 i=10
fmt.Println("第二个",i) //先执行这里,然后执行上面的
}
例子:
func f(){
for i:=0;i<5;i++{
defer fmt.Printf(“%d”,i)
}
}
这里打印的是4 3 2 1 0

defer用途

1、  关闭文件句柄

func read(){

file:=open(filename)

defer file.close()

}

2、  锁资源释放

func read(){

mc.Lock()

defer mc.Unlock()

//其他操作

}

3、  数据库连接的释放

func read(){

conn:=openDatabase()

defer conn.close()

//其他操作

}

注意:在程序出错的时候就不会执行defer了

defer后面是调用的函数,调用匿名函数

defer func (){

}()  //这里加上括号就是执行这个defer函数

defer执行匿名函数

package main

import (
"fmt"
) //匿名函数调用方式一
func test(a,b int)int{
result:=func(a int,b int) int{
return a+b
}(a,b) //由于这个是匿名函数,所以执行匿名函数就是在后面加上括号,把a和b传递进去
return result
} //匿名函数调用方式二
func test2(a,b int) int{
result:=func(a,b int)int{
return a+b
}
return result(a,b) //因为匿名函数地址给变量,所以变量来调用,如果不调用匿名函数,那么就调用变量的 方式
} func main(){
fmt.Println("方式一",test(100,200))
fmt.Println("方式二",test2(100,200))
} 还可以在全局定义匿名函数变量
package main
import(
“fmt”
)
var (
result=func(a,b int) int{
result=a+b
}
)
func main(){
fmt.Println(result(100,200))
}

匿名函数后面的括号就是执行匿名函数

三、golang时间、流程控、函数的更多相关文章

  1. postgreSQL时间、日期函数

    一.获取系统时间函数 1.1.获取当前完整时间 select now(); select current_timestamp; 1.2.获取当前日期 select currnt_date: 1.3.获 ...

  2. solidity高级理论(三):时间单位与view

    solidity高级理论(三):时间单位与view 关键字:时间单位.view.Gas优化 solidity使用自己的本地时间单位 变量 now 将返回当前的unix时间戳(自1970年1月1日以来经 ...

  3. UNIX环境编程学习笔记(11)——文件I/O之文件时间以及 utime 函数

    lienhua342014-09-16 1 文件的时间 每个文件都有三个时间字段,如表 1 所示. 表 1: 文件的三个时间字段 说明 字段 st_atime 文件数据的最后访问时间 st_mtime ...

  4. wpf 客户端【JDAgent桌面助手】开发详解(三) 瀑布流效果实现与UI虚拟化优化大数据显示

    目录区域: 业余开发的wpf 客户端终于完工了..晒晒截图 wpf 客户端[JDAgent桌面助手]开发详解-开篇 wpf 客户端[JDAgent桌面助手]详解(一)主窗口 圆形菜单... wpf 客 ...

  5. Python 关于时间和日期函数使用 -- (转)

    python中关于时间和日期函数有time和datatime   1.获取当前时间的两种方法: import datetime,time now = time.strftime("%Y-%m ...

  6. 数据库三,exec内置函数

    数据库三,exec内置函数 一.数据库查询与执行顺序 必备知识 查询语句的基本操作 - select - from - where - group by - having - distinct - o ...

  7. Linux下文件的三种时间标记:访问时间、修改时间、状态改动时间 (转载)

    在windows下,一个文件有:创建时间.修改时间.访问时间. 而在Linux下,一个文件也有三种时间,分别是:访问时间.修改时间.状态改动时间. 两者有此不同,在Linux下没有创建时间的概念,也就 ...

  8. SqlServer中日期和时间数据类型及函数 【转】

    来源:http://blog.csdn.net/royalwzy/article/details/6446075 日期和时间数据类型 下表列出了 Transact-SQL 的日期和时间数据类型. 数据 ...

  9. MySQL时间戳和时间格式转换函数

    MySQL时间戳和时间格式转换函数:unix_timestamp and from_unixtime unix_timestamp将时间转化成时间戳格式.from_unixtime将时间戳转化成时间格 ...

随机推荐

  1. git branch merge到master

    使用merge可以合并多个历史记录的流程. 如下图所示,bugfix分支是从master分支分叉出来的. 合并 bugfix分支到master分支时,如果master分支的状态没有被更改过,那么这个合 ...

  2. bat遍历当前目录下的文件,批量重命名

    @echo off setlocal enabledelayedexpansion for %%x in (*) do ( if not "%%x"=="demo.bat ...

  3. java 签名类 Signature

    java.security类 Signature java.lang.Object java.security.SignatureSpi java.security.Signature public ...

  4. dva解读1

    1.首先定义一个app对象实现dva const app = dva({ history: createHistory(), }); // 2. Plugins app.use(createLoadi ...

  5. Unity3d 多次显示关闭一个UI

    publicclass OpenClooseGoUI : MonoBehaviour { public  GameObject   closeBt; public  GameObject   goUI ...

  6. 实现 iPhone 电子书的分页显示功能的代码

     本文转载至 http://blog.csdn.net/zaitianaoxiang/article/details/6650497 原文地址:实现 iPhone 电子书的分页显示功能的代码作者:醉吻 ...

  7. 锁(java, DB)

    知识点 事务 锁(java, DB) 多线程知识点整理 锁(java, DB) 什么是锁 对资源的访问权限进行控制 如果把一个资源(对象)比喻成屋子.就好像你进入了屋子锁上了门.你家人和贼都进不去了. ...

  8. 【BZOJ3325】[Scoi2013]密码 Manacher

    [BZOJ3325][Scoi2013]密码 Description Fish是一条生活在海里的鱼.有一天他很无聊,就到处去寻宝.他找到了位于海底深处的宫殿,但是一扇带有密码锁的大门却阻止了他的前进. ...

  9. Strange Optimization(扩展欧几里得)

    Strange Optimization Accepted : 67   Submit : 289 Time Limit : 1000 MS   Memory Limit : 65536 KB Str ...

  10. OC中nil、Nil、NULL、NSNull的区别

    nil:指向OC中对象的空指针 e.g.: NSString *string = nil; Nil:指向OC中类的空指针    e.g.:Class class = Nil; NULL:指向其他类型的 ...