Go 对象构造

在使用go编程的时候,如果采用面向对象的方法,那么我们需要构造对象。而go语言并不是纯粹的面向对象语言,所以不像C++类似 的语言有默认构造函数,带参的构造函数,复制构造函数等。接下来,就来介绍下go 语言中如何构造对象

0x01 对象和方法

在面向对象编程中,对象的定义是具有属性和方法的集合体。所以在go中,用struct来定义的对象的属性。例如:

type Person struct{
   age int
}

对象一般都是有自己的方法的,在这个例子中,人可以有很多的行为。go中通过接收器将方法和类型对象绑定。例如:

   
func (p *Person)Sleep(){
       
}

通过上面的代码,我们就获得了一个通过面向对象方法定义的Person对象。

0x02 new 方法构造

new 为语言内置方法,创建一个传入其中类型的对象:

jessica := new(Person)

0x03 直接定义

在代码中需要使用对象的地方直接声明

jessica := Person{}
tom := &Person{}

0x04 定义构造函数

在C++中,我们构造函数和对象是一体的,如果我们不写构造函数,那么语言系统会使用默认的构造函数,在go中,上述两种方式使用了默认参数构造,不过 都是空类型,int的是0,在go中,我们通常在一个包中定义一个对象类型,并开放一个构造函数,构造对象返回:

package person
type person struct{
    age int
}

func NewPerson() *person {
    return &person{
    }
}

上面定义的方法可以看出,其是不传参的默认构造和使用系统提供的new函数没有差别。那如果我们需要构造的时候强制传入参数呢:

func NewPerson(age int) *person {
    return &person{
        age:age,
    }
}

上面的方法就是带参构造的情况。 那如果我们想要另一种情况,参数是可选的,如果不传,那就用默认构造,如果传了的话,就用传入的参数,那应该怎么写呢, 这个时候就需要通过go的闭包特性来是实现了。


package person

type person struct{
    opt Options
}

type Options struct{
    age int
}

type Option func(o *Options)

func newOptions(opts ...Option) Options {
    options := Options{
        age:15,
    }

    for _, o := range opts{
      o(&options)
    }
    return options
}

func Age(age int) Option{
    return func(o *Options){
        o.age = age
    }
}


func NewPerson(opts ...Option) *person{
    options := newOptions(opts...)
    return &person{
        opt:options,
    }
}

通过上面的代码我们可以看到,如果没有传入自定义的年龄,那对象构造出来的就是用默认年龄构造的对象。对象的构造就很灵活。

0x05 总结

上面我们介绍了GO 中对象的构造的几种方式。大家可以通过自己的需要来决定采用哪种方式。不同的方式,代码量是不一样的,所以慎选。options看着很 优美的,但是代码量还是很大的.

  1. 如果对象很简单,或者是允许对象中的某个属性为空,那么直接用内建的new方法或者直接声明。如前面提到的 0x02, 0x03 方式

  2. 如果参数较少,但是必须都要填参数,那么采用带参数的构造函数 如前面提到的 0x04 方式

  3. 如果在构造对象的时候参数或者属性可选,那么就可以采用 0x04 方式构造对象