1、strings和strconv的使用golang
strings算法
1.func HasPrefix(s, prefix string) bool 判断字符串s是否以prefix开头数据库
func main(){ a := "hello world" if (strings.HasPrefix(a,"hello")){ fmt.Println("yes") }else{ fmt.Println("no") } }
2.func HasSuffix(s, suffix string) bool 判断字符串s是否以prefix结尾安全
3.func Index(s, sep string) int 判断chars在s首次出现的位置,若是没有返回-1ide
4.func LastIndex(s, sep string) int 判断chars在s最后出现的位置,若是没有返回-1函数
5.func Replace(s, old, new string, n int) string 参数:原字符串,须要替换的,替换成,次数性能
func main(){ a := "hehehelololo" a = strings.Replace(a,"he","wo",2) fmt.Println(a) }
6.func Count(s, sep string) int 计数,sep在s中出现的次数ui
7.func Repeat(s string, count int) string 重复count次数spa
func main(){ a := strings.Repeat("he",3) fmt.Println(a) }
8.func TrimSpace(s string) string 去掉字符串首尾空白字符指针
9.func Trim(s string, cutset string) string 去除字符串首尾cutset字符
10.func TrimLeft(s string, cutset string) string 去掉字符串首cutset字符
11.func TrimRight(s string, cutset string) string 去掉字符串尾cutset字符
12.func Fields(s string) []string 以空格分隔,返回全部子字符串
f := func(c rune) bool { return !unicode.IsLetter(c) && !unicode.IsNumber(c) } fmt.Printf("Fields are: %q", strings.FieldsFunc(" foo1;bar2,baz3...", f)) # Fields are: ["foo1" "bar2" "baz3"]
13.func Join(a []string, sep string) string sep把字符串中的全部元素拼接
strconv
1.strconv.Itoa(i int) 把一个整数i转换成字符串
2.strconv.Atoi(str string)(int error) 把一个字符串转换成整数
详细见文档:http://docscn.studygolang.com/pkg/
2、时间和日期类型
time包
time.Time类型,用来表示时间
获取当前时间:now := time.Now()
time.Now().Day(),time.Now().Minute(),time.Now().Month(),time.Now().Year()
格式化
fmt.Printf("%02d/%02d/%02d %02d:%02d:%02d",now.Year()....) fmt.Printf(now.Format("02/1/2006 15:04:05")) fmt.Printf(now.Format("2006/1/02 15:04:05")) fmt.Printf(now.Format("2006/1/02")) # 时间必须是2006/1/02 15:04:05
func main(){ now := time.Now() fmt.Printf(now.Format("02/1/2006 15:04:05")) }
一些常量
const( Nanosecond Duration = 1 Microsecond = 1000*Nanosecond Millisecond = 1000*Microsecond Second = 1000*Millisecond Mintue = 60... Hour = 60... )
func test(){ time.Sleep(99*time.Millisecond) } func main(){ start := time.Now().UnixNano() test() end := time.Now().UnixNano() fmt.Println((end - start)/1000000) }
3、值类型与指针类型
1.普通类型,变量存的就是值,也叫值类型
2.获取变量的地址,用&,好比:var a int,获取a的地址:&a
3.指针类型,变量存的是一个地址,这个地址存的才是值h
4.获取指针类型所指向的值,使用:*,好比:var *p int,使用*p获取p指向的值
func main(){ a := 1 fmt.Println("a的地址:",&a) }
var n = 1 func modify1(n *int){ *n = 100 } func modify2(n int){ n = 200 } func main(){ modify1(&n) modify2(n) fmt.Println(n) } # n=100
4、流程控制
1.if/else分支判断
#形式一 if condition{ } #形式二 if condition{ }else{ } #形式三 if condition1{ }else if condition2{ }else if condition3{ }else{ } #注意:else与else if必须跟在花括号后面 if condition{ } else{ } //错误
2.switch case语句
switch var{ case var1: // fallthrough穿透(会继续执行,和其它语言没有加break效果同样,go不须要加break) case var2: case var3: default: } #写法1: switch var{ //能够多个值 case var1,var2: case var3, var4: case var5: default: } #写法2: var i = 0 switch{ condition1: condition2 default: } #写法3: switch i :=0{ //能够初始化 case var1,var2: case var3, var4: case var5: default: }
#随机生成0-100的整数,终端用户输入猜想的数字,提示大小... func main(){ rand.Seed(time.Now().Unix()) a := rand.Intn(100) var n int for{ fmt.Scanf("%d\n",&n) switch { case a < n: fmt.Println("大了") case a > n: fmt.Println("小了") default: fmt.Println("ok") return } } }
延展
Go的math/rand包提供了生成随机数的API,重要的API以下:
// 该函数设置随机种子 // 若不调用此函数设置随机种子,则默认的种子值为1,因为随机算法是固定的, // 若是每次都以1做为随机种子开始产生随机数,则结果都是同样的,所以通常 // 都须要调用此函数来设置随机种子,一般的作法是以当前时间做为随机种子 // 以保证每次随机种子都不一样,从而产生的随机数也不通 // 该函数协程安全 func Seed(seed int64) // 如下函数用来生成相应数据类型的随机数,带n的版本则生成[0,n)的随机数。 // 注意生成的随机数都是非负数 func Float32() float32 func Float64() float64 func Int() int func Int31() int32 // 注意该函数只返回int32表示范围内的非负数,位数为31,所以该函数叫作Int31 func Int31n(n int32) int32 func Int63() int64 func Int63n(n int64) int64 func Intn(n int) int func Uint32() uint32 func Uint64() uint64 // 另外,rand包还提供了一个类,接口和上面的大体相同: type Rand struct { // ... } // 建立一个以seed为种子的源,注意该源不是协程安全的 func NewSource(seed int64) Source // 以src为源建立随机对象 func New(src Source) *Rand // 设置或重置种子,注意该函数不是协程安全的 func (r *Rand) Seed(seed int64) // 下面的函数和全局版本的函数功能同样 func (r *Rand) Float32() float32 func (r *Rand) Float64() float64 func (r *Rand) Int() int func (r *Rand) Int31() int32 func (r *Rand) Int31n(n int32) int32 func (r *Rand) Int63() int64 func (r *Rand) Int63n(n int64) int64 func (r *Rand) Intn(n int) int func (r *Rand) Uint32() uint32 func (r *Rand) Uint64() uint64
package main import ( "fmt" "math/rand" "time" ) func main() { // // 全局函数 // rand.Seed(time.Now().Unix()) fmt.Println(rand.Int()) // int随机值,返回值为int fmt.Println(rand.Intn(100)) // [0,100)的随机值,返回值为int fmt.Println(rand.Int31()) // 31位int随机值,返回值为int32 fmt.Println(rand.Int31n(100)) // [0,100)的随机值,返回值为int32 fmt.Println(rand.Float32()) // 32位float随机值,返回值为float32 fmt.Println(rand.Float64()) // 64位float随机值,返回值为float64 // 若是要产生负数到正数的随机值,只须要将生成的随机数减去相应数值便可 fmt.Println(rand.Intn(100) - 50) // [-50, 50)的随机值 // // Rand对象 // r := rand.New(rand.NewSource(time.Now().Unix())) fmt.Println(r.Int()) // int随机值,返回值为int fmt.Println(r.Intn(100)) // [0,100)的随机值,返回值为int fmt.Println(r.Int31()) // 31位int随机值,返回值为int32 fmt.Println(r.Int31n(100)) // [0,100)的随机值,返回值为int32 fmt.Println(r.Float32()) // 32位float随机值,返回值为float32 fmt.Println(r.Float64()) // 64位float随机值,返回值为float64 // 若是要产生负数到正数的随机值,只须要将生成的随机数减去相应数值便可 fmt.Println(r.Intn(100) - 50) // [-50, 50)的随机值 }
3.for循环
for 初始化语句;条件判断;变量修改{ }
for与条件
for 条件{ }
func main(){ a := 5 for a<=10{ fmt.Println(a) a++ } }
for range语句
for i, v :=range str{ }
func main(){ str := "hello world" for i, v :=range str{ fmt.Printf("index:%v,value:%c\n",i,v) } }
for与continue及break
func main(){ a := 10 for i :=1 ;i < a; i++{ if (a%i==0){ continue }else if(i==9){ break } fmt.Println(i) } }
for与LABEL语句
// continue func main(){ for i :=1; i <=2; i++{ for j := 0; j <= 3; j++{ if (j == 2){ continue } fmt.Println(j) } } } #0 1 3 0 1 3 // LABEL func main(){ LABEL: for i :=1; i <=2; i++{ for j := 0; j <= 3; j++{ if (j == 2){ continue LABEL } fmt.Println(j) } } } #0 1 0 1
goto语句
//实现循环功能 func main(){ i := 0 HERE : i++ if i == 5{ return } fmt.Println(i) goto HERE }
5、函数
1.语法
func 函数名 (参数列表) [(返回值列表)]{}
//正确的写法 func add(a, b int){ } func add(a int) { }// 错误,花括号要和声明在同一行
2.golang函数特色
不支持重载,一个包不能有两个名字同样的函数
函数是一等公民,函数也是一种类型,一个函数能够赋值给变量
匿名函数
多返回值
package main import "fmt" // 函数也是一种类型 type add_func func(int, int) int func add(a int, b int)int{ return a + b } func operator(op add_func, a int, b int)int{ return op(a, b) } func main(){ //能够赋值给变量 c := add sum := operator(c,100,200) fmt.Println(sum) }
3.函数参数传递的方式:值传递和引用传递
不管是值传递仍是引用传递,传递给函数的都是变量的副本,不过,值传递是值的副本,
引用传递是地址的副本,通常来讲,地址拷贝更为高效,而值拷贝取决于拷贝的对象大小,对象越大,则性能越低
map、slice、chan、指针、interface默认以引用的方式传递
4.命名返回值的名字
func add(a, b int)(c int){ c = a + b return // 就不须要写成 // c := a + b // return c }
5._标识符,用来忽略返回值
func add(a int, b int)(int, int){ sum := a + b sub := a - b return sum, sub } func main(){ //使用_来标识不须要的返回值 sum, _:=add(200,100) fmt.Println(sum) }
6.可变参数
func add(arg...int)int{} //三个点修饰表示参数可变, 0个或多个参数 func add(a int, arg...int)int{} //一个或多个参数 //注意其中arg是一个slice,咱们能够经过arg[index]依次访问全部参数,经过len(arg)判断传递参数的个数
func t1(n int,arg...int)(sum int){ sum = n for i :=0; i < len(arg); i++{ sum += arg[i] } return } func main(){ s1 := t1(10) s2 := t1(10,20,30) fmt.Println(s1) fmt.Println(s2) }
7.defer用途
特性:
当函数返回时,执行defer语句,所以,能够用来作资源清理
多个defer语句,按先进后出的方式执行
defer语句中的变量,在Defer声明时就决定了
func main(){ var i int = 0 defer fmt.Println(i) defer fmt.Println("2") i = 10 fmt.Println(i) } // 10 2 0 // 能够反映三个特性
用途:
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() }
6、小练习
1.九九乘法表
package main import "fmt" func main(){ for i := 1; i <= 9; i++{ for j := 1; j<=i; j++{ val := j*i fmt.Printf("%d*%d=%d ",j,i,val) } } }
2.一个数若是刚好等于它的因子之和,这个数就被称为完数,如:6=1+2+3,找出1000内的全部完数
package main import "fmt" func check(n int)bool{ var sum int for i := 1; i <= n/2; i++{ fmt.Println(i) if (n % i == 0){ sum += i } } return sum == n } func main(){ var n int if (n == 0){ fmt.Println("no") } if (check(n)){ fmt.Println("yes") }else{ fmt.Println("no") } }
3.判断一个输入的字符串是否为回文(从左到右,从右到左同样)
package main import "fmt" func reserve(n string)(m string){ for i := 0; i < len(n); i++{ j := len(n) - i -1 m += string(n[j]) } return } func main(){ var n string fmt.Scanf("%s\n",&n) m := reserve(n) fmt.Println(n,m) if (m==n){ fmt.Println("true") }else{ fmt.Println("false") } } // 这种写法的问题是对于中文没法处理(中文3个byte)
//判断字符串回文 package main import "fmt" func check(n string)bool{ l := []rune(n) length := len(l) for i, _ := range l{ if (i == length/2){ break } if (l[i] != l[len(l) - i - 1]){ return false } } return true } func main(){ var n string fmt.Scanf("%s",&n) if (check(n)){ fmt.Println("yes") }else{ fmt.Println("no") } }
4.输入字符串,统计英文字母,空格,数字和其它字符的个数
5.计算两个大数相加的和,这个和可能会超过int64的表示范围
// 计算两个大数相加的和,这个和可能会超过int64的表示范围 package main import ( "fmt" "math" "strconv" "strings" // "reflect" ) func addLongNmber(n string, m string) (result string) { sign := 0 for i := len(n) - 1; i >= 0; i-- { sum := (n[i] - '0') + (m[i] - '0') if sign == 1 { sum++ sign-- } if sum >= 10 { sum -= 10 sign++ } result = strconv.Itoa(int(sum)) + result } if sign == 1 { result = "1" + result } return } func main() { var n, m string var part string = "0" fmt.Scanf("%s %s", &n, &m) repeatNum := int(math.Abs(float64(len(n) - len(m)))) part = strings.Repeat(part, repeatNum) if len(n) > len(m) { m = part + m } else { n = part + n } result := addLongNmber(n, m) fmt.Println(result) }