Go函数式选项模式

一.引入

  在编写代码时,当我们通过一个结果体构造一个新的对象时,往往会像下边这样,但如果结构体中有很多的字段,而且在构造新对象时只需要修改很少的字段,其它字段都使用默认值,用下边这种方式就会显得很笨重,这里我们就可以引入函数式选项模式的概念.

type student struct {
	name  string
	age   int
	class string
}

func main() {
	stu := student{"Alex", 20, "math"}
	stu2 := student{
		name: "alex",
		age:  40,
	}
}

   Functional options 是一种模式,在该模式中,你可以声明一个不透明的 Option 类型,该类型在某些内部结构中记录信息。你接受这些可变数量的选项,并根据内部结构上的选项记录的完整信息进行操作。

   将此模式用于构造函数和其他公共 API 中的可选参数,你预计这些参数需要扩展,尤其是在这些函数上已经有三个或更多参数的情况下。

二.示例

type student struct {
	name  string
	age   int
	class string
}

type stuOption func(*student)

func withAge(a int) stuOption {
	// 设置年龄
	return func(s *student) {
		s.age = a
	}
}

func withClass(c string) stuOption {
	// 设置课程
	return func(s *student) {
		s.class = c
	}
}

func newStudent(name string, options ...stuOption) *student {
	stu := &student{name: name, age: 20, class: "math"} // 年龄默认为20,课程默认为math
	for _, o := range options {
		o(stu)
	}
	return stu
}

func main() {
	s := newStudent("Lilith", withAge(10))
	s2 := newStudent("Ulrica", withAge(100), withClass("chinese"))
	fmt.Println(*s)    // {Lilith 10 math}
	fmt.Println(*s2)  // {Ulrica 100 chinese}
}

  上边代码中我们通过with*的形式给结构体变量赋值,在调用newStudent函数时,如果没有指定除name外的变量值就使用默认值,如s未指定class的值,结果class为默认值math,这样就可以更加灵活的对结构体进行修改,添加结构体变量时只需添加对应的with*函数即可.

 

posted @ 2022-04-18 14:55  屁桃  阅读(58)  评论(0编辑  收藏  举报