zoukankan      html  css  js  c++  java
  • 09-Go语言之指针和异常处理

    内容目录

    • 指针

    内容详细

    指针pointer

    • 普通变量存储的是对应类型的值,这些类型叫值类型

    • 指针也是一个变量,用于存储另一个变量的内存地址,变量存的是值,指针存的是一个地址,这个地址指向的空间存的才是值,所以指针又叫引用类型

    • 与变量类似,使用前需要声明

    • 声明指针并使用:指针取值时变量前面要加星号

    • 注意:不同类型的指针不能互相赋值,所以指针只能读,不能操作指针

      var 指针变量名 *指针类型
      
      func main() {
      	var a int = 20
      	var ip *int // 声明指针
      	ip = &a	// 指针存的是地址
      	fmt.Printf("a的地址:%x
      ",&a)
      	fmt.Printf("ip变量存储的指针地址:%x
      ",ip)
          
      	fmt.Printf("ip指向的变量的值:%d
      ",*ip) // 指针取值加星号
      }
      // a的地址:c000010090
      // ip变量存储的指针地址:c000010090
      // ip指向的变量的值:20
      
    • 指针和地址什么区别?

      • 地址:就是内存地址(用字节来描述的内存地址)
      • 指针:指针是带类型的
    • &*只有两个符号

      • &:表示取地址
      • *:根据地址取值

    指针可以修改数组

    // 接收的参数是一个数组的指针
    func modifyArray(a1 *[3]int){
    	(*a1)[0] = 100 // 修改指针内部的值
    	a1[1] = 200	// 语法糖也可以这样写
    }
    func main() {
    	a := [3]int{1,2,3}
    	modifyArray(&a)	 //把a以指针形式传参进修改的函数
    	fmt.Println(a)
    }
    

    空指针

    • 当一个指针被定义后没有分配到任何变量时,它的值为nil

    • 空指针的判断

      func main() {
      	var p *int
      	fmt.Println(p)
      	fmt.Printf("p的值 %x
      ",p)
      	// 空指针进行判断
      	if p!=nil {
      		fmt.Println("非空")
      	}else {
      		fmt.Println("空")
      	}
      }
      // <nil>
      // p的值 0
      // 空
      

    值传递和引用传递

    值类型

    var a int       // 0
    var b string    // 
    var c float32   // 0
    var e bool      // false
    

    引用类型

    • make()是给引用类型申请内存空间的

      var x []int // nil
      var m map[string]int  // nil
      

    new和make

    • new是用来初始化值类型指针的

      func main() {
      	// var a *int  声明a是一个int类型的指针
      	// 以上是错误的写法,因为声明后不能初始化,a只能是空指针
      	var a = new(int) // 得到一个int类型的指针
      	fmt.Println(a)
      
      	*a = 10			// 赋值给a的值
      	fmt.Println(a)
      	fmt.Println(*a)
      
      	var c = new([3]int)	// 得到一个3长度的int类型数组指针
      	fmt.Println(c)
      	c[0] = 1			// 赋值给第一个元素
      	fmt.Println(*c)
      }
      /*
      0xc000010090
      0xc000010090
      10
      &[0 0 0]
      [1 0 0]
      */
      
    • make只是用来初始化slice、map、chan的内存创建,而且它返回的类型就是这三个类型本身,而不是他们的指针类型,因为这三种类型就是引用类型,所以就没必要返回他们的指针了。

    panic和recover

    • panic是抛出异常

    • recover是捕获异常,必须与defer配合才能使用

    • 注意:defer一定要在可能引发panic的语句之前定义。

      func f1(){
      	defer func() {
      		// recover
      		err := recover()	// 尝试将函数从当前的异常状态恢复过来
      		fmt.Println("recover捕获到了panic异常", err)
      	}()
      
      	var a[]int
      	a[0] = 100 // 此时会报出panic错误
      	fmt.Println("panic之后")
      }
      
      func main() {
      	f1()
      	fmt.Println("这是main函数")
      }
      // recover捕获到了panic异常 runtime error: index out of range [0] with length 0
      // 这是main函数
      
    • 示例:

      func getCircleArea(radius float32) (area float32) {
      	if radius < 0 {
      		// 程序自己抛出异常
      		panic("半径不能为负数")
      	}
      	return 3.14 * radius * radius
      }
      
      func test(){
      	// 延时执行匿名函数
      	// 延时到何时?(1)程序正常结束  (2)程序发生异常
      	defer func() {
      		// recover()会返回程序为什么挂了
      		if err := recover();err !=nil{
      			fmt.Println(err)
      		}
      	}()
      	getCircleArea(-5)
      	fmt.Println("如果上一步程序错误,程序执行不到这里")
      }
      
      func test01(){
      	test()
      	fmt.Println("正常运行test01")// 程序在test出现异常后,照样会执行这一句,不会影响此函数中的执行代码
      }
      func main() {
      	test01()
      }
      // 半径不能为负数
      // 正常运行test01
      

    error类型:自定义错误后输出信息

    • error可以作为函数的返回值,是数据类型的一种

      // 函数返回值为error类型
      func getCircleArea(radius float32) (area float32, err error) {
      	if radius < 0 {
      		// 程序自己抛出异常,然后自定定义异常输出的信息
      		err = errors.New("半径不能为负")
      	}
      	area = 3.14 * radius * radius
      	return
      }
      
      func main() {
      	area, err := getCircleArea(-5)
      	// 处理异常:
      	if err != nil {
      		fmt.Println("错误信息为:", err)
      	} else {
      		fmt.Println("园的面积为:", area)
      	}
      }
      // 错误信息为: 半径不能为负
      
  • 相关阅读:
    【AtCoder】ARC075
    【BZOJ】3022: [Balkan2012]The Best Teams
    【Codeforces】Gym100633 D. LWDB
    MIME协议在邮件中的应用详解
    struts返回json数据
    mysql-存储过程(转载)
    安卓OKhttp请求封装
    安卓动态添加碎片
    通过163smtp服务器向各大邮箱发送邮件(SOCKET编程)
    安卓原生与hml交互(WebView基础)
  • 原文地址:https://www.cnblogs.com/lynlearnde/p/13822099.html
Copyright © 2011-2022 走看看