41. Go 进程执行
在上面的例子中,我们演示了一下如何去触发执行一个外部的进程。我们这样做的原因是我们希望从Go进程里面可以访问外部进程的信息。但有的时候,我们仅仅希望执行一个外部进程来替代当前的Go进程。这个时候,我们需要使用Go提供的 exec 函数。
package main
import "syscall"
import "os"
import "os/exec"
func main ( ) {
binary, lookErr := exec. LookPath ( "ls" )
if lookErr != nil {
panic ( lookErr)
}
args := [ ] string { "ls" , "-a" , "-l" , "-h" }
env := os. Environ ( )
execErr := syscall. Exec ( binary, args, env)
if execErr != nil {
panic ( execErr)
}
}
42. Go 经典hello world
我们的第一个例子是打印经典的“hello world”信息,我们先看下代码。
package main
import "fmt"
func main ( ) {
fmt. Println ( "hello world" )
}
43. Go 可变长参数列表
我支持可变长参数列表的函数可以支持任意个传入参数,比如fmt.Println函数就是一个支持可变长参数列表的函数。
package main
import "fmt"
func sum ( nums ... int ) {
fmt. Print ( nums, " " )
total := 0
for _ , num := range nums {
total += num
}
fmt. Println ( total)
}
func main ( ) {
sum ( 1 , 2 )
sum ( 1 , 2 , 3 )
nums := [ ] int { 1 , 2 , 3 , 4 }
sum ( nums... )
}
44. Go 命令行参数
命令行参数是一种指定程序运行初始参数的常用方式。比如 go run hello.go 使用 run 和 hello.go 参数 来执行程序。
package main
import "os"
import "fmt"
func main ( ) {
argsWithProg := os. Args
argsWithoutProg := os. Args[ 1 : ]
arg := os. Args[ 3 ]
fmt. Println ( argsWithProg)
fmt. Println ( argsWithoutProg)
fmt. Println ( arg)
}
45. Go 命令行参数标记
命令行参数标记是为命令行程序指定选项参数的常用方法。例如,在命令 wc -l 中, -l 就是一个命令行参 数标记。
package main
import "flag"
import "fmt"
func main ( ) {
wordPtr := flag. String ( "word" , "foo" , "a string" )
numbPtr := flag. Int ( "numb" , 42 , "an int" )
boolPtr := flag. Bool ( "fork" , false , "a bool" )
var svar string
flag. StringVar ( & svar, "svar" , "bar" , "a string var" )
flag. Parse ( )
fmt. Println ( "word:" , * wordPtr)
fmt. Println ( "numb:" , * numbPtr)
fmt. Println ( "fork:" , * boolPtr)
fmt. Println ( "svar:" , svar)
fmt. Println ( "tail:" , flag. Args ( ) )
}
46. Go 排序
Go的sort包实现了内置数据类型和用户自定义数据类型的排序功能。我们先看看内置数据类型的排序。
package main
import "fmt"
import "sort"
func main ( ) {
strs := [ ] string { "c" , "a" , "b" }
sort. Strings ( strs)
fmt. Println ( "Strings:" , strs)
ints := [ ] int { 7 , 2 , 4 }
sort. Ints ( ints)
fmt. Println ( "Ints: " , ints)
s := sort. IntsAreSorted ( ints)
fmt. Println ( "Sorted: " , s)
}
47. Go 切片
切片是Go语言的关键类型之一,它提供了比数组更多的功能。
package main
import "fmt"
func main ( ) {
s := make ( [ ] string , 3 )
fmt. Println ( "emp:" , s)
s[ 0 ] = "a"
s[ 1 ] = "b"
s[ 2 ] = "c"
fmt. Println ( "set:" , s)
fmt. Println ( "get:" , s[ 2 ] )
fmt. Println ( "len:" , len ( s) )
s = append ( s, "d" )
s = append ( s, "e" , "f" )
fmt. Println ( "apd:" , s)
c := make ( [ ] string , len ( s) )
copy ( c, s)
fmt. Println ( "cpy:" , c)
l := s[ 2 : 5 ]
fmt. Println ( "sl1:" , l)
l = s[ : 5 ]
fmt. Println ( "sl2:" , l)
l = s[ 2 : ]
fmt. Println ( "sl3:" , l)
t := [ ] string { "g" , "h" , "i" }
fmt. Println ( "dcl:" , t)
twoD := make ( [ ] [ ] int , 3 )
for i := 0 ; i < 3 ; i++ {
innerLen := i + 1
twoD[ i] = make ( [ ] int , innerLen)
for j := 0 ; j < innerLen; j++ {
twoD[ i] [ j] = i + j
}
}
fmt. Println ( "2d: " , twoD)
}
}
package main
import "fmt"
func main ( ) {
s1 := make ( [ ] int , 0 )
test ( s1)
fmt. Println ( s1)
}
func test ( s [ ] int ) {
s = append ( s, 3 )
}
package main
import "fmt"
func main ( ) {
s1 := make ( [ ] int , 0 )
s1 = test ( s1)
fmt. Println ( s1)
}
func test ( s [ ] int ) [ ] int {
s = append ( s, 3 )
return s
}
package main
import "fmt"
func main ( ) {
s1 := make ( [ ] int , 3 , 6 )
fmt. Println ( "s1= " , s1, len ( s1) , cap ( s1) )
s2 := append ( s1, 1 , 2 , 3 )
fmt. Println ( "s1= " , s1, len ( s1) , cap ( s1) )
fmt. Println ( "s2= " , s2, len ( s2) , cap ( s2) )
s3 := append ( s2, 4 , 5 , 6 )
fmt. Println ( "s1= " , s1, len ( s1) , cap ( s1) )
fmt. Println ( "s2= " , s2, len ( s2) , cap ( s2) )
fmt. Println ( "s3= " , s3, len ( s3) , cap ( s3) )
}
package main
import "fmt"
func main ( ) {
s1 := [ ] int { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 }
s2 := make ( [ ] int , 3 , 20 )
var n int
n = copy ( s2, s1)
fmt. Println ( n, s2, len ( s2) , cap ( s2) )
s3 := s1[ 4 : 6 ]
fmt. Println ( n, s3, len ( s3) , cap ( s3) )
n = copy ( s3, s1[ 1 : 5 ] )
fmt. Println ( n, s3, len ( s3) , cap ( s3) )
}
48. Go 请求处理频率控制
频率控制是控制资源利用和保证服务高质量的重要机制。Go可以使用goroutine,channel和ticker来以优 雅的方式支持频率控制。
package main
import "time"
import "fmt"
func main ( ) {
requests := make ( chan int , 5 )
for i := 1 ; i <= 5 ; i++ {
requests <- i
}
close ( requests)
limiter := time. Tick ( time. Millisecond * 200 )
for req := range requests {
<- limiter
fmt. Println ( "request" , req, time. Now ( ) )
}
burstyLimiter := make ( chan time. Time, 3 )
for i := 0 ; i < 3 ; i++ {
burstyLimiter <- time. Now ( )
}
go func ( ) {
for t := range time. Tick ( time. Millisecond * 200 ) {
burstyLimiter <- t
}
} ( )
burstyRequests := make ( chan int , 5 )
for i := 1 ; i <= 5 ; i++ {
burstyRequests <- i
}
close ( burstyRequests)
for req := range burstyRequests {
<- burstyLimiter
fmt. Println ( "request" , req, time. Now ( ) )
}
}
49. Go 时间
Go提供了对时间和一段时间的支持。这里有一些例子。
package main
import "fmt"
import "time"
func main ( ) {
p := fmt. Println
now := time. Now ( )
p ( now)
then := time. Date ( 2009 , 11 , 17 , 20 , 34 , 58 , 651387237 , time. UTC)
p ( then)
p ( then. Year ( ) )
p ( then. Month ( ) )
p ( then. Day ( ) )
p ( then. Hour ( ) )
p ( then. Minute ( ) )
p ( then. Second ( ) )
p ( then. Nanosecond ( ) )
p ( then. Location ( ) )
p ( then. Weekday ( ) )
p ( then. Before ( now) )
p ( then. After ( now) )
p ( then. Equal ( now) )
diff := now. Sub ( then)
p ( diff)
p ( diff. Hours ( ) )
p ( diff. Minutes ( ) )
p ( diff. Seconds ( ) )
p ( diff. Nanoseconds ( ) )
p ( then. Add ( diff) )
p ( then. Add ( - diff) )
}
50. Go 时间戳
程序的一个通常需求是计算从Unix起始时间开始到某个时刻的秒数,毫秒数,微秒数等。
package main
import "fmt"
import "time"
func main ( ) {
now := time. Now ( )
secs := now. Unix ( )
nanos := now. UnixNano ( )
fmt. Println ( now)
millis := nanos / 1000000
fmt. Println ( secs)
fmt. Println ( millis)
fmt. Println ( nanos)
fmt. Println ( time. Unix ( secs, 0 ) )
fmt. Println ( time. Unix ( 0 , nanos) )
}