strings.HasPrefix(s string, prefix string) bool :判断字符串s是否以prefix开头
范例:自动在输入的url前面加上 “http://” 末尾加上 “/”
package main
import (
"fmt"
"strings"
// "strconv"
)
func main(){
var n string
fmt.Println("Input Your Web Urls:")
fmt.Scanf("%s",&n)
n=http_ch(n)
n=http_ch_end(n)
fmt.Printf("Your url is ========> [%s]",n)
}
//自动在web的URL前面添加 "http://""
func http_ch(url string) string {
if strings.HasPrefix(url,"http://"){
return url
} else {
return fmt.Sprintf("http://%s",url)
}
}
//自动在web的URL末尾添加 "/"
func http_ch_end(url string) string {
if strings.HasSuffix(url,"/"){
return url
} else {
return fmt.Sprintf("%s/",url)
}
}
1.strings.Index(s string, str string) int
判断str在s中首次出现的位置,如果没有出现,则返回-1
2.strings.LastIndex(s string, str string) int
判断str在s中最后出现的位置,如果没有出现,则返回-1
3.==strings.Replace(str string, old string, new string, n int)==
字符串替换
str_a="hello wid"
result:=strings.Replace(str_a,"i","or")
执行后,result的值为hello word
4.strings.Count(str string, substr string)int
计算substr字符在字符串str中出现的次数
5.strings.Repeat(str string, count int)string
将str字符串重复count次
6.strings.ToLower(str string)string
将字符串全部转为小写
7.strings.ToUpper(str string)string
将字符串全部转为大写
1.strings.TrimSpace(str string)
去掉字符串首尾空白字符(类似python的.strip()方法)
2.strings.Trim(str string, cut string)
去掉字符串首尾cut字符
3.strings.TrimLeft(str string, cut string)
去掉字符串首cut字符
4.strings.TrimRight(str string, cut string)
去掉字符串尾cut字符
1.strings.Field(str string)
返回str空格分隔的所有子串的slice(类似python的.split()方法)
strings.Field('jk iu 123')
==结果为>>>> ["jk","iu","123"]
2.strings.Split(str string, split string)
返回str split分隔的所有子串的slice
strings.Split('jk#iu#123','#')
==结果为>>>> ["jk","iu","123"]
第一种Field方法相当于:strings.Split(str string, ” “)
strings.Join(s1 []string, sep string)
用sep把s1中的所有元素链接起来
把一个整数i转成字符串
把一个字符串转成整数
var str_b string = "1980"
num,err := strconv.Atoi(str_b)
if err !=nil { //输入错误时,执行这步。比如:当str_b为"1980x"时会执行这步
fmt.Printf("你应该输入一个整数类似的字符串,%s",err)
}
fmt.Println(num)
时间类型在time包中,ime.Time类型,用来表示时间。
now := time.Now()
now输出为 2018-08-21 17:32:23.5956001 +0800 CST m=+0.012000001
一个完整的时间格式,很明显我们用不了这么多的数据
方法一 : 使用 time.Now().Day(),time.Now().Minute(),time.Now().Month(),time.Now().Year() 这些方法,别可以输入当前的 日、分、月、年,然后可以使用printf格式化的输出:
例如:
package main
import (
"time"
"fmt"
)
func main() {
fmt.Printf("%d-%02d-%02d",time.Now().Year(),time.Now().Month(),time.Now().Day()) //%02d表示至少使用2个位数表示
}
输出结果为:
2018-08-19
方法二 :* 使用time.Now()自带的Format方法,Format里面是时间格式显示模板,并且模板内的年必须是2006、月必需是01、日必需是02、时必需是15(或3)、分必需是04。模板展示的效果才生效。然后根据Format模板
里面的格式来显示日期
不要问我模板内展示的日期为什么必需要用 2006年01月02日15时04分,据说是go语言诞生的时间,我可以吐槽下有点自恋吗 -.-!
time.Now().Format(“2006-01-02”) : 表示使用 “年-月-日” 的方式来显示,显示结果为 2018-08-19
time.Now().Format(“20060102”) : 表示使用 “年月日” 的方式来显示,显示结果为 20180819
time.Duration 用来表示纳秒
time.second 用来表示秒
其他常量:
const (
Nanosecond Duration = 1 //纳秒
Microsecond = 1000 * Nanosecond //微秒
Millisecond = 1000 * Microsecond //毫秒
Second = 1000 * Millisecond //秒
Minute = 60 * Second //分
Hour = 60 * Minute //时
和C语言里的指针一样,指针存储了变量的内存地址并指向变量
var <指针名称> [指针类型]*
指针类型表示指针要指向什么类型的变量。范例:
var p1 *int //一个执行整数类型的指针
var p2 *string //一个执行字符串类型的指针
指针存储的是变量的地址,因此应该把变量的内存地址赋给指针,
如何获取变量的内存地址
和C语言里面一样,使用 “&” 这个取址符号来取变量的地址,比如取a变量的内存地址就是>>> “&a”
var p1 *int
int_a :=10
p1 = &int_a
指针执行变量的值
指针存储了变量的内存地址,使用 “*” 号可以将指针指向变量的值,比如上面的赋值范例,使用 *p1
就表示执行变量int_a的值,就是10。
var p1 *int
int_a :=10
p1 = &int_a
fmt.Println(*p1)
结果为
10
指针传入函数
func main() {
var p1 *int
int_a :=10
p1 = &int_a
mac(p1)
fmt.Println(int_a)
}
func mac(p *int){
*p = 20
return
}
执行结果为
20
请注意指针传入函数时,对指针指向的值的改变也会应用到变量中,此时指针指向的值在函数中已经不是局部变量了
格式1,简单的判断:
if <条件> {
…执行语言
}
格式2,带else的判断:
if <条件> {
…执行语言
} else {
…执行语句
}
格式3,带else if的的判断:
if <条件> {
…执行语言
} else if <条件> {
…执行语句
} else if <条件> {
…执行语句
} else {
…执行语句
}
else if可以写很多个
if判断中的else if饱受诟病,当然switch就是为解决此来的。switch大体上分为2种写法:
需要注意除非有关键字 fallthrough ,否则在执行一个满足的case条件的语句后,整个语句结束
写法1范例:
var i=0
switch i {
case 0:
fmt.Println("equa 0")
//fallthrough 表示向下执行一个case条件内的语句
case 1:
fmt.Println("equa 1")
case 3,4,5:
fmt.Println("equa 3 or 4 or 5")
default:
fmt.Println("equa 0")
}
switch后面有变量,case后面只能是值的形式
写法2范例:
var i=0
switch {
case i==0:
fmt.Println("equa 0")
case i>0:
fmt.Println("more than 0")
case i<0 && i !=-5: //可以使用逻辑与/或表示多条件
fmt.Println("less than 0 but not equa -5")
default:
fmt.Println("equa 0")
}
switch后面无变量,case后面是条件判断的形式
go的for循环和c语言的十分类似,只是没有小括号,并且需要注意下变量的赋值(以 := 的方式赋值)
格式: for 初始化语句; 条件判断; 变量修改 { 循环语句块 }
范例:
//输出从1到100的整数
for i:=1;i<=100;i++ { //i++相当于i=i+1
fmt.Println(i)
}
for循环写法二 for 条件判断 {}
此格式多用于无限循环(不是死循环,内部你得有个break跳出循环的关键字和触发此关键字的条件)情况:
//输出从1到100的整数
var i=1
for {
fmt.Println(i)
i=i+1
if i>100{
break
}
}
for循环配合range关键字能实现对数组、slice、map、chan的遍历,使用范例:
var str1="abcde" //字符串是特殊的数组
for i,j:=range str1{ //i表示下标;j表示元素,这里是字符
fmt.Println(i,string(j)) //string将字符转为字符串,否则是ACII码的形式
break、continue
break表示终止整个循环。continue表示停止本次循环,继续下一次的循环
for i:=0;i<100;i++{
if i == 25 { //i值为25时,停止本次循环,从26开始继续循环
continue
}
if i > 50{ //i值大于50时,终止循环
break
}
fmt.Println(i)
}
上面范例执行后,只输出0到50的整数,除了25
goto 和 label 语句
label是一个大写的英文标识符,通常和goto、continue关键字组合使用来控制程序的流程
func main() {
//continue 到label
LABEL1:
for i := 0; i <= 5; i++ {
for j := 0; j <= 5; j++ {
if j == 4 {
continue LABEL1 ////回到 LABEL1这个lable,然后向下执行
}
fmt.Printf("i is: %d, and j is: %d\n", i, j)
}
}
//goto到label
i := 0
HERE:
print(i)
i++
if i == 5 {
return
}
goto HERE //回到HERE这个lable,然后向下执行。
}
go中的函数不支持重载,一个包不能有两个名字一样的函数。并且和python一样,函数可以赋给变量: func def1(){...} ... c:=def1
函数def1只是表示了一个内存地址。
声明语法: ==func 函数名 (参数列表) [(返回值列表)] { …函数体… }==
(返回值列表)是写上返回值的类型(也可以写上形式返回值),函数的参数可以有多个,返回值也一样可以有多个。函数的声明范例如下:
func add() { //简单的函数声明
...
}
func add(a int,b int) { //带参数的函数声明
...
}
func add(a int,b int) int { //带2个整数参数、带1个整数返回值的函数声明
...
}
func add(a ,b int) (int,int){ //带2个整数参数(参数类型相同时,可以简写)、带2个整数返回值的函数声明
...
}
func add(a ,b int,c string) str1 sting { //带2个整数参数1个字符串参数,带一个字符串返回值的函数声明。并且函数体中可以将返回值赋予str1
...
}
无论是值传递,还是引用传递,传递给函数的都是变量的副本,不过,值传递是值的拷贝。引用传递是地址的拷贝,一般来说,地址拷贝更为高效。而值拷贝取决于拷贝的对象大小,对象越大,则性能
越低。
package main
import "fmt"
func modify(a int) { //值传递
a = 100
}
func modify_ar(a *int) { //引用传递,传入的是指针
*a = 100 //修改指针指向的地址内的值
}
func main() {
a := 8
fmt.Println(a) //值为8
modify(a) //因为是值传递,函数内为局部变量,因此不会修改全局a变量的值
fmt.Println(a) //值仍然为8
modify_ar(&a) //引用传递,传入的是变量的内存地址,函数体内如果对指向地址内的值修改,则被传入地址的变量值也会改变
fmt.Println(a) //值变为了100
}
go函数的形式参数可以为一个函数,需要指定“函数参数”的类型,如 函数的传入参数类型和传出参数类型,只需要类型(int、float32、string)即可
“函数参数”的格式: ==func (参数类型) 返回参数类型==
范例:
func oper (a func(int,int) int,b int,c int) int { //此函数形式参数a的类型为函数类型
return a(b,c)
}
上面范例只要将符合的传入函数传入oper就可以了,传入函数只要有2个整形参数,并且返回一个整数类型的值就符合要求,比如下面的函数就可以作为传入函数:
func add(a,b int) int {
return a+b
}
result:=oper(add,10,20)
函数的传入参数为函数时,使用类似“func(int,int) int”的格式表示晓得比较复杂,如果需要的传入函数比较复杂的话,可能要写很长的函数格式,因此可以使用 “type” 关键字来定义一个“函数 ”数据类型
(因为函数也是一种数据类型):
type my_def func(int,int) int //定义一个函数数据类型
func oper (a my_def,b int,c int) int { //此函数形式参数a的类型不是系统自带的类型,而是自定义的my_def类型,而my_def是一个函数数据类型
return a(b,c)
}
go函数体中,有“defer”关键字,关键字后面跟的操作将会暂停执行,在接下来的函数体内其他操作结束后,再来操作defer关键字后面的操作。
func example(a,b int) {
defer fmt.Printf("%d",a+b) //遇到defer就暂停后面的操作,等待下面语句的操作完成后再来操作
fmt.Printf("%d+%d=",a,b)
}
func main(){
example(10,20)
}
执行结果:
10+20=30
上面的范例中,函数在执行时,遇到了defer 关键字,因此 “fmt.Printf(“%d”,a+b)” 暂时不执行,而往下执行下面的“fmt.Printf(“%d+%d=”,a,b)”,执行完后,函数体内没有其他的操作了,再返回去执行defer后面的“defer fmt.Printf(“%d”,a+b)”
如果函数中有多个“defer”关键字,则 最先使用 “defer” 的最后执行
defer使得函数具有延缓执行的特性,非常适合添加在那些程序结束后必须要进行的步骤,比如打开一个文件操作后在最后必须关闭句柄。这在具有多个流程判断的程序中非常好用
//关闭文件句柄
func file_oper(){
file := open(c:\log.txt)
defer file.Close()
if ... {
...
return
}
...
}
//锁资源释放
func read() {
mc.Lock()
defer mc.Unlock()
//其他操作
}
//数据库连接释放
func read() {
conn := openDatabase()
defer conn.Close()
//其他操作
}
go函数参数可以允许输入任意多个参数,参数的个数是动态的可变的。在函数定义时,形式参数使用“arg…<参数类型>”表示可以传入动态个数的参数,函数体中,传入的参数都存在arg这个数组中。这个和python函数的动态参数
def function1(*a)
比较类似,函数体中,所有传入的参数都在a这个元组内
可变参数
var sum int
func add_args(a int,args...int) int { //第一位置是1个整数类型的参数,后面的参数个数动态随机
for i:=0;i//如何遍历动态参数
sum:=sum+agrs[i]
}
return a+sum
}
不必声明函数的名称,直接声明然后就调用。被传入的参数写在匿名函数最后
func main() {
func(a int,b int) { //匿名函数,直接打印结果
fmt.Println(a+b)
}(10,20) //传入的参数10和20
}
执行结果
30
package main
import (
"fmt"
)
type my_def func(int,int) int
func main() {
fmt.Println(oper(sub,90,80))
fmt.Println(args(10,11,12,12,33,40))
func(a int,b int) {
fmt.Println(a+b)
}(10,20)
example(10,20)
}
func sub(a,b int) int{
return a*b
}
func oper(a my_def,b,c int) int {
return a(b,c)
}
func args(a int,args...int) int {
var sum int
for i:=0;i<len(args);i++{
sum=sum+args[i]
}
return a+sum
}
func example(a,b int) {
defer fmt.Printf("%d",a+b) //遇到defer就暂停后面的操作,等待下面语句的操作完成后再来操作
fmt.Printf("%d+%d=",a,b)
}
执行结果
7200
118
30
10+20=30