zoukankan      html  css  js  c++  java
  • Go-day02

    Go程序的基本结构

      ***func init() 会在main函数之前执行

      1.包中的函数调用

        a.同一个包中函数,直接调用

        b.不同包中函数,通过包名+点+函数名进行调用

           2.包的访问控制规则

        a.大小写意味着这个函数/变量是可导出的

        b.小写意味着这个函数/变量是私有的,包外部不能访问

     练习题一:

      写一个程序,对于给定一个数字n,求出所有两两相加等于n的组合。
      比如: 对于n=5,所有组合如下所示:
        0+5=5
        1+4=5
        2+3=5
        3+2=5
        4+1=5
        5+0=5

    package main
    
    import (
    	"fmt"
    )
    
    //两个数加和,遍历一个数然后另外一个数就是和减去当前值
    func list(n int){
    	for i := 0; i <= n ; i++ {
    		fmt.Printf("%d+%d=%d
    ",i,n -i ,n)
    	}
    }
    func main() {
    	list(10)
    }
    
    
    /*
    0+10=10
    1+9=10
    2+8=10
    3+7=10
    4+6=10
    5+5=10
    6+4=10
    7+3=10
    8+2=10
    9+1=10
    10+0=10
    */

    练习题二:

      包别名的应用,开发一个程序,使用包别名来访问包中的函数?

    package main
    
    import(
         a "add" //设置别名
    )
    
    func main () {
    
    fmt.Println("result:", a.Name)
    fmt.Println("result:", a.age)
    }
    

    init的加载顺序

    package main
    
    import "fmt"
    var a string = "xxxxx"  //加载顺序:先初始化全局变量,在初始化init,在执行main
    var age int = 100
    
    func init(){
    	a  = "xx"
    	age =  10
    }
    func main() {
    	fmt.Println("a",a,"age",age)
    }
    

     

    main函数引入包的加载顺序(包中导入包):

      程序的初始化和执行都起始于main包。如果main包还导入了其它的包,那么就会在编译时将它们依次导入。有时一个包会被多个包同时导入,那么它只会被导入一次(例如很多包可能都会用到fmt包,但它只会被导入一次,因为没有必要导入多次)。当一个包被导入时,如果该包还导入了其它的包,那么会先将其它包导入进来,然后再对这些包中的包级常量和变量进行初始化,接着执行init函数(如果有的话),依次类推。等所有被导入的包都加载完毕了,就会开始对main包中的包级常量和变量进行初始化,然后执行main包中的init函数(如果存在的话),最后执行main函数

    包只初始化 不引用

    _操作其实是引入该包,而不直接使用包里面的函数,而是调用了该包里面的init函数。
    package main
    
    import (
          _	"fmt" //下划线加空格 只初始化 不引用
    )
    
    
    func main() {
    
    	
    }
    

     Go中的常量const

      永远只读,不可以被修改

    ***最后一个const c = getValue()是不可以的,因为函数的返回值不确定

    练习:

      定义两个常量Man=1和Female=2,获取当前时间的秒数,如果能被Female整除,则在终端打印female,否则打印man

    package main
    
    import (
    	"time"
    	"fmt"
    )
    
    const (
    	Man = 1
    	Female = 2
    )
    
    
    
    func main() {
    
    	Second :=  time.Now().Unix()
    	if (Second % Female == 0){
    		fmt.Println("female",Female)
    	}else {
    		fmt.Println("man",Man)
    	}
    
    }
    

     Go变量

      1.int初始值为0

      2. string初始值为""

          3.bool初始值为false

    练习:

      获取操作系统和path

    package main
    
    import (
    	"os"
    	"fmt"
    )
    
    func main(){
    	var goos string = os.Getenv("GOOS")
    
    	fmt.Printf("The operating system is %s
    ",goos)
    
    	path := os.Getenv("PATH")
    	
    	fmt.Printf("Path is %s
    " ,path)
    
    }
    

     32位操作系统指针是4字节,64位操作系统指针是8字节

    值类型与引用类型

      1.值类型,int,float,bool,string,数组和struct(结构体)

      2.引用类型,指针,slice(切片),map,chan都是引用类型

    package main
    
    import (
    	"fmt"
    )
    func main() {
    	a := 5
    	b := make(chan int,1)
    	fmt.Println("a= ",a)
    	fmt.Println("b= ",b)
    }
    
    /*
    a=  5
    b=  0xc420050070
    */
    

    练习:

    package main
    
    import (
    	"fmt"
    )
    
    func modify(a int){
    	a = 10 //函数属于值类型
    	return
    }
    func modify1(p *int) {
         *p = 100
    	//指针是引用类型 所有会改变
    }
    func main() {
    	a := 5
    	b := make(chan int,1)
    	fmt.Println("a= ",a)
    	fmt.Println("b= ",b)
    	modify(a)
    	fmt.Println("a= ",a)
    	modify1(&a)
    	fmt.Println("a= ",a)
    }
    
    /* 
    
    a=  5
    b=  0xc420050070
    a=  5
    a=  100
    */
    

    练习:

      将first和second值交换(通过指针改变内存地址后的源数据)

    package main
    
    import (
    	"fmt"
    )
    
    func swap(a *int,b *int){
    	tmp := *a
            *a = *b
            *b = tmp
    
    }
    
    
    func main() {
    	first :=100
    	second :=200
    	swap(&first,&second)
    	fmt.Println("first= ",first)
    	fmt.Println("second= ",second)
    
    }
    
    /*
    first=  200
    second=  100
    */
    

     第二种方法:

    package main
    
    import (
    	"fmt"
    )
    
    func swap1(a int,b int) (int,int) {
    	return b,a
    }
    
    
    func main() {
    	first :=100
    	second :=200
    	//swap(&first,&second)
    	first,second = swap1(first,second)
    	fmt.Println("first= ",first)
    	fmt.Println("second= ",second)
    
    }
    
    
    /*
    first=  200
    second=  100
    */
    

    局部变量和全局变量使用

    package main
    import (
    	"fmt"
    
    )
    
    
    var a string  = "M" //定义了个全局变量
    
    
    
    func main() {
    	a := "G" //局部变量
    	fmt.Println("from main",a) //找自己的局部变量
    	f1()
    }
    func f2()  {
    	fmt.Println("from f2",a) //局部变量没有,找全局的a
    }
    
    func f1(){
    	a:="O"
    	fmt.Println("from f1",a)
    	f2()//执行f2函数相当于重新引用不会继承自己的局部变量
    }
    /*GOM*/

    ***重点观察

    package main
    import (
    	"fmt"
    
    )
    
    
    var a = "G"
    
    
    
    func main() {
    	n()
    	m()
    	n()
    
    }
    
    func n (){
    	fmt.Println(a)
    }
    
    func m (){
    	a = "O" //将a赋值成O,因为m中未定义a所以修改的是全局的a
    	fmt.Printf(a)
    }
    
    /*
    GOO
    */
    

     ***重点观察

    package main
    import (
    	"fmt"
    
    )
    
    var a string  //定义了个全局变量
    
    func main() {
    	a = "G" //局部变量,因为当前未生命a变量,所以修改的是全局的a
    	fmt.Println("from main",a) //找自己的局部变量
    	f1()
    }
    func f2()  {
    	fmt.Println("from f2",a) //局部变量没有,找全局的a,这是全局的a已经被更改为G
    }
    
    func f1(){
    	a:="O" //重新在函数内声明var a string = "O"
    	fmt.Println("from f1",a)
    	f2()//执行f2函数相当于重新引用不会继承自己的局部变量
    }
    
    /*
    GOG
    */
    

     数据类型和操作符

      1.int8和uint8的区别?

        uint8是无符号int,比int少一位 符号如:"+","-"

      2.不同类型可以转换例子如下:

    package main
    
    import (
    	"fmt"
    )
    
    func test() {
    
    	var a int8 = 100
    	var b int16 = int16(a) //将a的int8转换成int16赋值给b
    	fmt.Printf("a=%d , b=%d" , a,b)
    }
    
    
    func main() {
    	test()
    }
    

      3.int32是4字节,int64是8字节 

    练习

      使用math/rand生成10个随机整数,10个小于100的随机整数,10个随机浮点数

    package main
    
    import (
    	"math/rand"
    	"fmt"
    	"time"
    )
    
    func init(){
    	//放到初始化里
    	rand.Seed(time.Now().UnixNano()) //以时间戳做为当前随机数的种子,Nano是纳秒
    }
    func main() {
    
    	for i := 0 ; i < 10 ; i++ {
    		a := rand.Int() //获取整数
    		fmt.Println(a)
    	}
    	for i := 0 ;i < 10 ; i++{
    		a := rand.Intn(100) //获取100以内的随机整数
    		fmt.Println(a)
    	}
    	for i := 0 ; i < 10 ; i++ {
    		a := rand.Float32() //获取浮点数
    		fmt.Println(a)
    	}
    }
    

     字符和字符串

      1.字符byte var a  byte = 'c' 一个byte占用1个字节 8位 ***字符必须是单引号

      2.字符串由多个字符组成

          3.字符串""与``的区别

        ``可以保存原有格式原封不动打印

    package main
    
    import "fmt"
    
    func main() {
    	var str = "hello world 
    "
    	var str1 = `
    	go go go ,
    	1231 123
    	`
    	var b  byte = 'c'
    	fmt.Println(str)
    	fmt.Println(str1)
    	fmt.Println(b) //默认是数字标识
    	fmt.Printf("%c
    ",b) //字符格式化输出
    
    }
    
    /*
    hello world 
    
    
    	go go go ,
    	1231 123
    	
    99
    c
    
    */
    

     fmt格式化输出详解

    /*
    一般:
    
    	%v	相应值的默认格式。在打印结构体时,“加号”标记(%+v)会添加字段名
    	%#v	相应值的Go语法表示
    	%T	相应值的类型的Go语法表示
    	%%	字面上的百分号,并非值的占位符
    布尔:
    
    	%t	单词 true 或 false。	
    整数:
    
    	%b	二进制表示
    	%c	相应Unicode码点所表示的字符
    	%d	十进制表示
    	%o	八进制表示
    	%q	单引号围绕的字符字面值,由Go语法安全地转义
    	%x	十六进制表示,字母形式为小写 a-f
    	%X	十六进制表示,字母形式为大写 A-F
    	%U	Unicode格式:U+1234,等同于 "U+%04X"
    浮点数及其复合构成:
    
    	%b	无小数部分的,指数为二的幂的科学计数法,与 strconv.FormatFloat
    		的 'b' 转换格式一致。例如 -123456p-78
    	%e	科学计数法,例如 -1234.456e+78
    	%E	科学计数法,例如 -1234.456E+78
    	%f	有小数点而无指数,例如 123.456
    	%g	根据情况选择 %e 或 %f 以产生更紧凑的(无末尾的0)输出
    	%G	根据情况选择 %E 或 %f 以产生更紧凑的(无末尾的0)输出
    字符串与字节切片:
    
    	%s	字符串或切片的无解译字节
    	%q	双引号围绕的字符串,由Go语法安全地转义
    	%x	十六进制,小写字母,每字节两个字符
    	%X	十六进制,大写字母,每字节两个字符
    指针:
    
    	%p	十六进制表示,前缀 0x
    
    */
    
    
    package main
    
    import "fmt"
    
    func main() {
    	var a int = 100
    	var b bool
    	c := 'a'
    
    	fmt.Printf("%v
    ",a) //相应值的默认格式。在打印结构体时
    	fmt.Printf("%#v
    ",b)
    	fmt.Printf("%T
    ",c) //相应值的类型的Go语法表示
    	fmt.Printf("90%%
    ") //百分比
    	fmt.Printf("%b
    ",a) //二进制显示
    	fmt.Printf("%f
    ",199.22) //浮点数显示
    	fmt.Printf("%q
    ","this is a str") //单引号围绕的字符字面值,由Go语法安全地转义
    	fmt.Printf("%p
    ",&a) //打印内存地址
    
    	//将一个int类型转化成str 不能用强制转换
    
    	str := fmt.Sprintf("%d",a)
    	fmt.Printf("%q
    ",str)
    
    }
    
    
    /*
    result: 100 false int32 90% 1100100 199.220000 "this is a str" 0xc42007e008 "100" */

     用Go实现字符串反转

    package main
    
    import "fmt"
    
    func reverse(str string) (string){
    	var result string
    	strLen := len(str)
    	for i := 0 ; i < strLen; i++ {
    		result = result + fmt.Sprintf("%c",str[strLen -i -1]) 
    	}
    	return result
    }
    
    func main() {
    	myStr:= "hello world"
    	result := reverse(myStr)
    	fmt.Println(result)
    }
    
    /*
    dlrow olleh
    */
    

      通过数组反转

    package main
    
    import "fmt"
    
    func reverse_arry(str string) (string){
    	var result []byte //定义一个空数组
    	length := len(str)
    	for i := 0 ; i < length ; i++ {
    		result = append(result,str[length -i -1]) //通过append往数组里追加值
    	}
    	return string(result) //最后在string化
    }
    
    func main() {
    	myStr:= "hello world"
    	result = reverse_arry(myStr)
    	fmt.Println(result)
    }
    

     Go的字符串操作

    package main
    
    import "fmt"
    
    func main() {
    	str := "hello"
    	str1 := "world"
    
    	//result := str + " " +str1
    	result := fmt.Sprintf("%s %s", str, str1) //字符串拼接
    	q := result[6:] //字符串切片
    	fmt.Println(result)
    	fmt.Println(q)
    }
    
    /*
    
    hello world
    world
    */
    

     练习:

      求100到200的素数,用户随便输入

    package main
    
    import (
    	"fmt"
    	"math"
    )
    
    
    func isPrime(n int ) bool{
    
    	for i := 2 ; i < int(math.Sqrt(float64(n))) ; i++ { //素数是大于1的自然数除了1和他本身不能有其他整除,类似于奇数
    		if n % i == 0 {
    			return false
    		}
    
    	}
    	return true
    }
    
    func main() {
    	var n int
    	var m int
    	fmt.Scanf("%d%d",&n,&m) //类似于python的input输入,传入Scanf函数是指针,这样就可以确保函数外定义的变量可以修改值
    
    	for i := n ; i < m ; i++ {
    		if isPrime(i) == true{
    			fmt.Printf("%d
    ",i)
    			continue
    		}
    	}
    
    
    }
    

       打印出100-999中所有的“水仙花数”,所谓“水仙花数”是指一个三位数,其各位数字立方和等于该数本身。例如:153 是一个  “水仙花数”,因为 153=1 的三次方+5 的三次方+3 的三次方

    package main
    
    import "fmt"
    
    func isNumber(num int) bool{
    	a := num % 10
    	b := (num / 10) % 10
    	c := (num / 100) % 10
    	res := a*a*a + b*b*b + c*c*c
    	return res == num
    }
    
    func main() {
    	var n int
    	var m int
    	fmt.Scanf("%d%d",&n,&m)
    	for i := n ; i < m ; i ++ {
    		if isNumber(i) == true{
    			fmt.Println("this is a shuixianhua = ",i)
    		}
    	}
    }
    
    /*
    1  999
    this is a shuixianhua =  1
    this is a shuixianhua =  153
    this is a shuixianhua =  370
    this is a shuixianhua =  371
    this is a shuixianhua =  407
    */
    

    通过ascii码实现水仙花:

    package main
    
    import (
    	"fmt"
    	"strconv"
    )
    
    func main() {
    	var str string
    	fmt.Scanf("%s" ,&str)
    
    	var result = 0
    	for i := 0 ; i < len(str) ; i++ {
    		sum := int(str[i] - '0') //字符串切片默认是ascii码,通过ascii与0做运算 0代表48(十进制),1代表49(十进制)做差仍为1
    		result += (sum * sum * sum)
    	}
    
    	number,err := strconv.Atoi(str) //将字符串转化为int
    	if (err != nil) {
    		fmt.Printf("cat not convert %s to int 
    ",number)
    		return
    	}
    
    	if result == number{
    		fmt.Printf("%d is shuixianhua 
    ",number)
    
    	}else{
    		fmt.Printf("%d is not shuixianhua
    " ,number)
    	}
    
    }
    

    对于一个数n,求n的阶乘之和,即: 1! + 2! + 3!+...n!

    package main
    
    import "fmt"
    
    func sum(n int ) uint64{
    	var s uint64 = 1
    	var sum uint64 = 0
    	for i := 1; i <= n ; i++ {
    		s = s * uint64(i) //和乘以当前值 就是下一位阶乘的结果
    		fmt.Printf("%d!=%v
    ",i,s)
    		sum += s //这是阶乘的和
    	}
    	return sum
    }
    
    func main() {
    	var n int
    
    	fmt.Scanf("%d", &n)
    
    	s := sum(n)
    	fmt.Println(s)
    
    }
    
    /*
    10
    1!=1
    2!=2
    3!=6
    4!=24
    5!=120
    6!=720
    7!=5040
    8!=40320
    9!=362880
    10!=3628800
    4037913
    */
    
  • 相关阅读:
    实验吧(你真的会PHP吗)CTF之代码审计最终版---解析是错的 我的才是对的
    php的intval函数
    memcached 查看所有的key
    kvm 启动libvirtd时出现错误
    mysql三种binlog日志的理解
    mysql连接提示1030
    执行curl -sSL 提示curl: (35) SSL connect error
    tomcat线程数查看
    docker 1.12.3版本搭建私有仓库,上传镜像报错:server gave HTTP response to HTTPS client”
    memcached安装
  • 原文地址:https://www.cnblogs.com/liujiliang/p/8986727.html
Copyright © 2011-2022 走看看