zoukankan      html  css  js  c++  java
  • go package包的使用

    一、标准库

    • 引入
        在我们之前所写的所以代码中,我们基本上可以看到fmt这个导入的包,但是我们却不知道如何去写这种包。
        如果我们可以自己去写,那么我们就可以将一个功能的集合统一的放入包中,便于以后使用,那么我们如何去写这种包呢?
    
    • go的标准库
        在将自定义包之前我们可以先简单的看一下,fmt 我们是从哪里导过来的?我们可以自己去自己的GOROOT/src 下去查看,你们可以看到大致如下的包
        src/
          |- archive
          |- bufio
          |- builtin
          |- bytes
          .....
    
        这一些的包,这些包我们称之为 go的标准库
        想这样的包go 一共给我们提供来150个以上
    

    二、自定义包

    • 包的声明
    package pakName  // 此行必须写在第一行,且一个文件夹下的所有文件必须使用同一个包名
    
    • 包的导入
    import (     // 导入包名必须写在package 包的声明下面
        pak
        ....
    )
    
    • 实例

      day14/calculator/calc.go

        package calc
    
        import "errors"
    
        func Calc(num1,num2 int,operator string) (int,error){
            switch  operator{
        	case "+":
        		return sum(num1,num2),nil
        	case "-":
        		return red(num1,num2),nil
        	case "*":
        		return ride(num1,num2),nil
        	case "/":
        		return exc(num1,num2),nil
        	default:
        		return 0,errors.New("不合法的运算符")
        	}
        }
    
    • 解释
        pack calc
        声明 day14/calculator/calc.go 属于calc 包
        一个go文件有且仅输入一个包,一个包可以有多个go文件
    
        import errors
        导入标准库  errors 包
    
        func Calc(){}
        // 声明函数Calc ,
        // 在go语言中 变量、类型、函数、方法 首字母大写表示 外部可以访问
    

    三、关于包的使用

    3.1 自定义calc 包

    • 目录
        day14/
            |- calc.go
            |- exc.go
            |- red.go
            |- ride.go
            |- sum.go
    
    • calc.go
        package calc
    
        import "errors"
    
        func Calc(num1,num2 int,operator string) (int,error){
        	switch  operator{
        	case "+":
        		return sum(num1,num2),nil
        	case "-":
        		return red(num1,num2),nil
        	case "*":
        		return ride(num1,num2),nil
        	case "/":
        		return exc(num1,num2),nil
        	default:
        		return 0,errors.New("不合法的运算符")
        	}
        }
    
    • exc.go
        package calc
    
        func exc(num1,num2 int)int{
        	return num1 / num2
        }
    
    • red.go
        package calc
        func red(num1,num2 int)int{
        	return num1 - num2
        }
    
    • ride.go
        package calc
        func ride(num1,num2 int)int{
        	return num1 * num2
        }
    
    • sum.go
        package calc
        func sum(num1,num2 int)int{
        	return num2 + num1
        }
    
    • 注意事项
     1、
     day14/calculator文件夹下每个文件的声明 都是
     package calc
     表明 calculator下的所有文件(不包含文件夹)都属于calc包
    
     2、
     calculator文件夹的文件已经是calc包下的文件了,如果声明成其他包名,则编译会无法通过
    
     3、
     一个go文件有且仅属于一个包,一个包可以有多个go文件组成
    
     4、
     包的命名要简洁、清晰且全小写
    

    3.2 使用自定义包

    • 调用calc包
      day14/example1/main.go
        package main
    
        import (
        	"day17/day14/calculator"
        	"fmt"
        )
    
        func main(){
        	var (
        		num1 int = 12
        		num2 int = 4
        	)
    
        	result,err := calc.Calc(num1,num2,"-")
        	if err != nil{
        		fmt.Println(err)
        		return
        	}
        	fmt.Printf("运算结果为:%v
    ",result)
        }
    
    • 注意事项
        外部调用calc包,只能使用Calc函数,如果使用calc包中的sum,exc,ride..这些方法,则会编译报错
        因为calc包中 只有Calc函数允许外部访问,因为Calc 方法大写开头,所以允许外部访问
    
        再次强调
          包中的变量、类型、函数、方法,只有大写字母开头才能够被外部调用
    

    四、结构体之包的使用

    • 结构体工厂
      day14/baozi/factory.go
    package baozi
    
    import "fmt"
    
    // 创建工厂结构体
    type baozi struct{
    	Kind string // 包子的种类
    }
    
    func (this *baozi) Product(){
    	switch this.Kind {
    	case "rou":
    		fmt.Println("生产了一个肉包")
    	case "cai":
    		fmt.Println("生产了一个菜包")
    	default:
    		fmt.Println("生产了一个未知包")
    	}
    }
    
    func NewBaozi(kind string)*baozi{
    	return &baozi{kind}
    }
    
    • 包子工厂类的讲解
    1、
    type baozi struct{
    	Kind string // 包子的种类
    }
    在包子 包中我们创建了一个结构体,但是该结构体外部无法访问使用,
    因为小写字母开头,只能内部使用
    
    2、
    func NewBaozi(kind string)*baozi{
    	return &baozi{kind}
    }
    在包子 包中提供了一个函数NewBaozi,只能通过调用NewBaozi创建baozi结构体
    
    3、
    为什么我们要通过NewBaozi函数创建结构体,而不直接使用baozi.baozi的方式创建呢?
    通过函数创建结构体口可以忽略创建的细节。
    
    
    • 如何使用包子包中的结构体
      day14/example2/main
    package main
    
    import (
    	"day17/day14/baozi"
    	"fmt"
    )
    
    func main(){
    	//baozi := baozi.baozi{"rou"}  // 无法使用,因为baozi结构体 小写开头
    	baozi := baozi.NewBaozi("rou")
    	fmt.Println("包子的种类",baozi.Kind)
    	baozi.Product()
    }
    
    包子的种类 rou
    生产了一个肉包
    

    五、包的初始化init

    day17/da14/test/init.go

    package test
    
    import "fmt"
    
    func init(){
    	fmt.Println("test -- init")
    }
    
    func Test(){
    	fmt.Println("this is test.test")
    }
    
    

    day17/da14/test1/init.go

    package test1
    
    import "fmt"
    
    func init(){
    	fmt.Println("test1 -- init")
    }
    
    

    day17/da14/emample3/main.go

    package main
    
    import (
    	"fmt"
    	"day17/day14/test"
    	_ "day17/day14/test1"   // _ 表示只执行init 函数,因为我们并不需要所有的函数
    )
    
    func init(){
    	fmt.Println("main -- init ")
    }
    
    func main(){
    	fmt.Println("main--main")
    	test.Test()
    }
    
    
    执行结果:
    test -- init
    test1 -- init
    main -- init 
    main--main
    this is test.test
    
    结论:
    1、init 函数会在main 函数之前执行
    2、go 程序会更具导入包的顺序依次执行每一个包的init 函数
    

    六、程序加载过程

    程序加载过程

    如果喜欢看小说,请到183小说网

  • 相关阅读:
    C++并发与多线程学习笔记--unique_lock详解
    C++并发与多线程学习笔记--互斥量、用法、死锁概念
    MongoDB教程--配置与入门
    C++并发与多线程学习笔记--多线程数据共享问题
    C++并发与多线程学习笔记--参数传递详解
    C++并发与多线程学习笔记--基本概念和实现
    Python学习笔记--语音处理初步
    C#中三个关键字params,Ref,out
    Windows窗体应用开发3--配置标准控件1
    在博客的第一天
  • 原文地址:https://www.cnblogs.com/xiaobaiskill/p/10648179.html
Copyright © 2011-2022 走看看