如何强制像 OOP 中的构造函数一样填充结构中的所有字段?

How can I force all fileds in struct to be filled like constructor in OOP?

摘要与代码

我正在学习没有 class 但有 struct 的 Golang 和 Nim,并且对这些语言很陌生。习惯了 OOP,我尝试使用 struct 做一个类似 class 的东西,但发现 struct 的字段是可选的。为了编写严格的代码,我想将它们变成强制性的。

JAVA

class Person {
    String Name
    int Age
    Person(String Name, int Age) {
        this.Name = Name;
        this.Age = Age;
    }
}
// Ok
Person p1 = new Person("John Doe", 30);
// FAILS
Person p2 = new Person("John Doe");

Golang

type Person struct {
    Name    string
    Age     int
}
// Ok
p1 := Person{
    Name:   "John Doe",
    Age:    30,
}
// Ok
p2 := Person{
    Name:   "John Doe",
}

解决方案之一是实现一个初始化struct的函数;如果参数没有完全传递,它将失败。

Golang

func newPerson(Name string, Age int) Person {
    return Person{
        Name:   Name,
        Age:    Age,
    }
}
// Ok
p1 := newPerson("John Doe", 30)
// FAILS
p2 := newPerson("John Doe")

问题

我觉得上面的解决方案是多余的,因为 init 函数必须与每个结构一起出现。这种方法是否流行或有更好的解决方案?

在 Golang 中,您可以使用类似构造函数的工厂函数(如您在上面定义的那个)来在初始化结构时初始化默认值。

是的,这是正确的解决方案,选择这种解决方案有几个优点。我列出了其中的一些:

  1. 您将仅在必要时实现工厂函数,从而避免不必要的输入。
  2. 完全控制对象构造,即如果初始化不成功,您可以通过将函数签名设为 func newPerson(Name string, Age int) (Person, error) 轻松 return 错误。在构造函数中这是不可能的。
  3. 在其他语言中实现构造函数与在 Golang 中实现工厂函数没有什么不同。

除了上述优点之外,由于您可以在任何需要的地方直接实例化结构,工厂函数有助于避免重复初始化默认值。