Swift中的一步对象创建和属性初始化?

Tru*_*an1 9 properties instance swift swift2

有没有办法将属性值分配给类实例,即使它不是init构造函数中的参数?例如,在C#中我可以这样做:

public class Student
{
   public string firstName;
   public string lastName;
}

var student1 = new Student();
var student2 = new Student { firstName = "John", lastName  = "Doe" };
Run Code Online (Sandbox Code Playgroud)

注意student2我仍然可以在初始化期间分配值,即使类中没有构造函数.

我在文档中找不到你是否可以为Swift做这样的事情.如果没有,有没有办法在初始化期间使用extensions扩展Student类来分配属性值?

我正在寻找这个的原因是我可以在一个数组中添加一堆实例,而无需为每个学生实例显式创建变量,如下所示:

var list = new[] {
  new Student { firstName = "John", lastName  = "Doe" },
  new Student { firstName = "Jane", lastName  = "Jones" },
  new Student { firstName = "Jason", lastName  = "Smith" }
}
Run Code Online (Sandbox Code Playgroud)

在Swift中实现这一目标的任何原生或优雅方式?

Jon*_*nah 11

您有几个选项,具体取决于您希望如何配置此类型以及哪种语法最方便.

您可以定义一个方便的初始化程序,它接受您要设置的属性.如果您始终设置相同的属性,则非常有用,如果您设置的是一组不一致的可选属性,则无用.

public class Student
{
    public var firstName:String?;
    public var lastName:String?;
}

extension Student {
    convenience init(firstName: String, lastName: String) {
        self.init()
        self.firstName = firstName
        self.lastName = lastName
    }
}

Student(firstName: "Any", lastName: "Body")
Run Code Online (Sandbox Code Playgroud)

您可以定义一个便捷初始化程序,它接受一个块来配置新实例.

extension Student {
    convenience init(_ configure: (Student) -> Void ) {
        self.init()
        configure(self)
    }
}

Student( { $0.firstName = "Any"; $0.lastName = "Body" } )
Run Code Online (Sandbox Code Playgroud)

您可以将Ruby的tap方法模仿为扩展,以便您可以在方法链的中间操作对象.

extension Student {
    func tap(block: (Student) -> Void) -> Self {
        block(self)
        return self
    }
}

Student().tap({ $0.firstName = "Any"; $0.lastName = "body"})
Run Code Online (Sandbox Code Playgroud)

如果最后一个有用,您可能希望能够采用tap任何对象.我不认为您可以自动执行此操作,但您可以定义默认实现以使其更容易:

protocol Tap: AnyObject {}

extension Tap {
    func tap(block: (Self) -> Void) -> Self {
        block(self)
        return self
    }
}

extension Student: Tap {}

Student().tap({ $0.firstName = "Any"; $0.lastName = "body"})
Run Code Online (Sandbox Code Playgroud)


Dan*_*ieu 7

我只是想指出,如果你的结构是不可变的,你可以只使用 astruct而不是 a class,你将免费获得一个隐式初始化器:

只需将其粘贴到游乐场并将结构更改为类,您就会明白我的意思。

struct Student
{
    var firstName : String?
    var lastName : String?
}

var student = Student(firstName: "Dan", lastName: "Beaulieu")
Run Code Online (Sandbox Code Playgroud)


Leo*_*bus 5

如果您的类没有必需的初始化程序,则可以在返回新的Student对象之前使用闭包方法设置Student属性,如下所示:

public class Student {
    var firstName = String()
    var lastName = String()
}

let student1 = Student()
let student2: Student  = {
    let student = Student()
    student.firstName = "John"
    student.lastName  = "Doe"
    return student
}()

print(student2.firstName)  // John
print(student2.lastName)  // Doe
Run Code Online (Sandbox Code Playgroud)