简体   繁体   English

如何在 Swift 中初始化结构或 class?

[英]How can I initialize a struct or class in Swift?

I have a struct called Person in this code in the down, I am creating an instance of it, like this one:我在下面的代码中有一个名为 Person 的结构,我正在创建它的一个实例,如下所示:

let peson: Person = Person(name: "Dan", age: 21)

But I noticed that we can make it with this code as well:但我注意到我们也可以使用以下代码实现它:

let peson: Person = { Person(name: "Dan", age: 21) }()

So what is the difference?那么区别是什么呢? When I should use first way and when I should use second way?什么时候应该使用第一种方式,什么时候应该使用第二种方式?

struct Person {

    var name: String
    var age: Int
    
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
    
}

This is the Swift equivalent of what JS calls an Immediately invoked funciton expression (IIFE)这是 Swift 等效于 JS 调用的立即调用函数表达式 (IIFE)

{ Person(name: "Dan", age: 21) } is a closure, of type () -> Person . { Person(name: "Dan", age: 21) }是一个闭包,类型为() -> Person

{ Person(name: "Dan", age: 21) }() calls this closure, passing no arguments (since it has no parameters), and returns the new Person . { Person(name: "Dan", age: 21) }()调用这个闭包,不传递 arguments (因为它没有参数),并返回新的Person The result evaluated to just a Person .结果评估为一个Person

You could nest this any number of times.你可以嵌套这个任意次数。 You could even do:你甚至可以这样做:

let person: Person = {{{{{{{{{{ Person(name: "Dan", age: 21) }()}()}()}()}()}()}()}()}()}()

or或者

let person: Person = {{{{{{{{{{ Person(name: "Dan", age: 21) }}}}}}}}}}()()()()()()()()()()

But there's obviously no point.但显然没有任何意义。 You code would be most idomaticly written as:你的代码最典型地写成:

let person = Person(name: "Dan", age: 21)

When you want to perform multiple operations while initializing, using closures will help you keep the code clean.当您想在初始化时执行多个操作时,使用闭包将帮助您保持代码干净。 See example snippet below -请参阅下面的示例片段 -

struct Person {
    var name: String
    var age: Int
    var maritalStatus: MaritalStatus?
    
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
    
    init (name: String, age: Int, maritalStatus: MaritalStatus) {
        self.init(name: name, age: age)
        self.maritalStatus = maritalStatus
    }
    
    enum MaritalStatus: String {
        case single = "Single"
        case married = "Married"
        case divorced = "Divorced"
    }
}

let person1 = Person(name: "Jonn", age: 10)
let person2: Person = {
    var person = Person(name: "Bob", age: 26)
    person.maritalStatus = .married
    return person
}()
let person3 = Person(name: "Sam", age: 45, maritalStatus: .divorced)

In the above example, person1 and person3 are initialozed with different initilizers, but person 2 assigns the maritalStatus property differently.在上面的示例中,person1 和 person3 使用不同的初始化程序进行初始化,但 person 2 分配 maritalStatus 属性的方式不同。

Now consider initializations when you want to change mulitple properties on a object, for example UIView - initializing it, changing the corner radius, assigning a background view, adding pre-selected sub views etc., such closure style of initialization is very helpful.现在,当您想更改 object 上的多个属性时,请考虑初始化,例如 UIView - 对其进行初始化、更改角半径、分配背景视图、添加预选的子视图等,这种关闭样式的初始化非常有用。

The anonymous closure is an unnamed function.匿名闭包是一个未命名的 function。 It's useful whenever you want to initialize something with the result of calling a function, but you don't want to write a function like:每当您想使用调用 function 的结果来初始化某些东西时,它很有用,但您不想编写 function,例如:

  func makeDan() -> Person {
     ...
  }

  let person = makeDan()

That would mean you have to come up with a name for the function and find some place to put it, which means it's also visible and can be called by other pieces of code that don't need anything to do with makeDan.这意味着您必须为 function 命名并找到放置它的地方,这意味着它也是可见的,并且可以由不需要与 makeDan 有任何关系的其他代码段调用。 It's often useful to have functions that have no names.拥有没有名称的函数通常很有用。

Needing a function to initialise something is useful when you have something complex that needs some kind of computation, so multiple lines of stuff.当你有一些复杂的东西需要某种计算时,需要一个 function 来初始化一些东西很有用,所以多行的东西。 It's also useful when the initialization is only wanted to be done if/when required:当只希望在需要时/在需要时进行初始化时,它也很有用:

lazy var dan: Person = { ... }()

Perhaps because the computation is expensive in some kind of resource use, like cpu or memory.也许是因为在某种资源使用中计算成本很高,例如 cpu 或 memory。 Or possibly because the computation involves some kind of side effect, like opening a database or something, that's only wanted if/when the property is used.或者可能是因为计算涉及某种副作用,比如打开数据库或其他东西,只有在使用属性时才需要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM