Java vs Golang:结构体、函数及指针

结构体的声明和使用

在Golang中区别与Java最显著的一点是,Golang不存在“类”这个概念,组织数据实体的结构在Golang中被称为结构体。函数可以脱离“类”而存在,函数可以依赖于结构体来调用或者依赖于包名调用。

Golang中的结构体放弃了继承、实现等多态概念,结构体之间可使用组合来达到复用方法或者字段的效果。

要声明一个结构体只需使用type + struct关键字即可:

type Person struct {
	Name string
	Age  int
	id   string
} 

使用结构体:

    personPoint := new(entity.Person) // 通过new方法创建结构体指针
	person1 := entity.Person{} // 通过Person{}创建默认字段的结构体
	person2 := entity.Person{ // 通过Person{Name:x,Age:x}创建结构体并初始化特定字段
		Name: "Jrobin",
		Age:  24,
	}
	fmt.Println(personPoint) // &{ 0 }
	fmt.Println(person1)     // { 0 }
	fmt.Println(person2)	 // {Jrobin 24 }

函数和方法的区别

函数:源于面向过程编程

方法:源于面向对象编程

在Java中,所有的函数都包含在类中,因此在Java中,函数和方法属于同一个概念。

而在Golang中,函数不基于结构体而是基于包名调用,方法基于结构体调用。

  • entity
package entity

import "fmt"

type Person struct {
	Name string
	Age  int
	id   string
}

// Person结构体/指针可调用的"方法",属于Person结构体
func (p *Person) Solve() {
	fmt.Println(p)
}

// 任何地方都可调用的"函数",不属于任何结构体,可通过entity.Solve调用
func Solve(p *Person) {
	fmt.Println(p)
}
  • main
func main() {
	personPoint := new(entity.Person) // 通过new方法创建结构体指针

	entity.Solve(personPoint) // 函数调用
	
	personPoint.Solve() 	  // 方法调用
} 

指针的使用

C/C++存在显示指针操作,而且指针的使用非常灵活复杂,也是C/C++的独特之处。

在Java中不存在显式的指针操作。

而Golang中存在显式的指针操作,但是Golang的指针不像C那么复杂,不能进行指针运算。

Golang使用 * 来定义和声明指针,通过&来取得对象的指针。

  • Golang
func main() {
	p1 := entity.Person{
		Name: "Jrobin",
		Age:  24,
	}
	changePerson(p1)
	fmt.Println(p1.Name) // Jrobin
	changePersonByPointer(&p1)
	fmt.Println(p1.Name) // zhuzhen
}

func changePersonByPointer(person *entity.Person) {
	person.Name = "zhuzhen"
}

func changePerson(person entity.Person) {
	person.Name = "zhuzhen"
}

  • java
public class Main {

    public static void main(String[] args) {

        Person person=new Person();
        person.name="Jrobin";
        person.age=24;

        changePerson(person);
        System.out.println(person.name);  //zhuzhen
        
        int num=10;
        changeNum(num);
        System.out.println(num);  //10

    }

    private static void changePerson(Person person){
        person.name="zhuzhen";
    }
    
    private static void changeNum(int num){
        num=20;
    }

}
 

Java和Golang方法传参时传递的都是值类型,在Java中如果传递了基本类型,则会传递一个副本,方法中的操作不会改变原始的变量值;如果传递了引用类型(对象、数组等)会复制其指针进行传递, 而在Golang中必须要显式传递Person的指针,不然只是传递了该对象的一个副本。

注意,如果结构体中需要组合其他结构体,那么建议采用指针的方式去声明,否则会出现更新丢失问题。

以下是Golang方法的一个隐式指针转换,结构体调用方法时,如果传递的是对象,那么会被自动转化为指针调用:

type Person struct {
	Name string
	Age  int
}

// Person结构体/指针可调用的"方法",属于Person结构体
func (p *Person) Solve() {
	fmt.Println(p)
}


func main() {
	p := entity.Person{
		Name: "Jrobin",
		Age:  24,
	}
	
	pp := &p
	pp.Solve() // 显式
	
	p.Solve    // 隐式,自动将p转化为&p
}

在Golang中,对结构体进行"&"取地址操作,视为对该类型进行一次new的实例化操作。

你可能感兴趣的:(go,java,golang,go,指针,多态)