Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/93.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 创建第一个中间名和姓氏时选择_Ios_Swift - Fatal编程技术网

Ios 创建第一个中间名和姓氏时选择

Ios 创建第一个中间名和姓氏时选择,ios,swift,Ios,Swift,我想创建一个函数,可以检查一个人是否输入了他们的中间名,或者变量是否为“空”(即nil)。如果它不是空的,它将基本上打印人名、中间名和全名,如果不是空的,它应该忽略中间名,如果值为“nil”(即为),则打印出名字和姓氏。不管出于什么原因,它都不会在没有中间名的情况下打印person2FirstName和person2LastName(我希望它这样做) 我这样做是为了练习在Swift中使用选项。虽然我知道这是一种在理论上保护代码的方法,但在实践中,我对它的理解非常糟糕。如果你能给我任何帮助,我将不

我想创建一个函数,可以检查一个人是否输入了他们的中间名,或者变量是否为“空”(即nil)。如果它不是空的,它将基本上打印人名、中间名和全名,如果不是空的,它应该忽略中间名,如果值为“nil”(即为),则打印出名字和姓氏。不管出于什么原因,它都不会在没有中间名的情况下打印person2FirstName和person2LastName(我希望它这样做)

我这样做是为了练习在Swift中使用选项。虽然我知道这是一种在理论上保护代码的方法,但在实践中,我对它的理解非常糟糕。如果你能给我任何帮助,我将不胜感激

let person2FirstName: String =  "Steve"
let person2MiddleName: String? = "nil"
let person2LastName: String =  "Jones"

if person2MiddleName != nil {
"\(person2FirstName) \(person2MiddleName) \(person2LastName)"
} else {
"\(person2FirstName) \(person2LastName)"
}
我不断地发现这些错误:

main.swift:14:23: warning: string interpolation produces a debug description for an optional value; did you mean to make this explicit?
"\(person2FirstName) \(person2MiddleName) \(person2LastName)"
                      ^~~~~~~~~~~~~~~~~~~
main.swift:14:24: note: use 'String(describing:)' to silence this warning
"\(person2FirstName) \(person2MiddleName) \(person2LastName)"
                      ~^~~~~~~~~~~~~~~~~~
                       String(describing:  )
main.swift:14:24: note: provide a default value to avoid this warning
"\(person2FirstName) \(person2MiddleName) \(person2LastName)"
                      ~^~~~~~~~~~~~~~~~~~
                                         ?? <#default value#>
main.swift:14:1: warning: string literal is unused
"\(person2FirstName) \(person2MiddleName) \(person2LastName)"
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.swift:16:1: warning: string literal is unused
"\(person2FirstName) \(person2LastName)"
main.swift:14:23:警告:字符串插值为可选值生成调试说明;你的意思是要说清楚吗?
“\(person2FirstName)\(person2MiddleName)\(person2LastName)”
^~~~~~~~~~~~~~~~~~~
main.swift:14:24:注意:使用“String(description:)”使此警告静音
“\(person2FirstName)\(person2MiddleName)\(person2LastName)”
~^~~~~~~~~~~~~~~~~~
字符串(描述:)
main.swift:14:24:注意:提供默认值以避免此警告
“\(person2FirstName)\(person2MiddleName)\(person2LastName)”
~^~~~~~~~~~~~~~~~~~
?? 
main.swift:14:1:警告:字符串文字未使用
“\(person2FirstName)\(person2MiddleName)\(person2LastName)”
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.swift:16:1:警告:字符串文字未使用
“\(person2FirstName)\(person2LastName)”
简短回答:

如果让进行测试,则使用
,而不是针对
nil
进行测试。这将“展开”变量,使其不再是可选的

而不是:

if foo != nil {
    doSomethingWith(foo) // WARNING: foo is optional!
}
这样做:

if let unwrappedFoo = foo {
    doSomethingWith(unwrappedFoo) // No warnings!
}
长答覆:

这里似乎有很多变量,其中许多是逻辑分组的。Person1FirstName、Person1MiddleName、Person1LastName、Person2FirstName、。。。人名。。。等等。您可以通过在结构中将它们组合在一起来简化此过程,如下所示:

struct Person {
    let firstName: String
    let middleName: String?
    let lastName: String
}
现在,我们可以添加一个方便的初始值设定项和一个方便的属性来生成全名:

struct Person {
    let firstName: String
    let middleName: String?
    let lastName: String

    init(firstName: String, middleName: String? = nil, lastName: String) {
        self.firstName = firstName
        self.middleName = middleName
        self.lastName = lastName
    }

    var fullName: String {
        if let middleName = self.middleName {
            return "\(self.firstName) \(middleName) \(self.lastName)"
        } else {
            return "\(self.firstName) \(self.lastName)"
        }
    }
}
(初始值设定项不是绝对必要的,因为编译器将自动为我们生成一个初始值设定项,但使用手动编写的初始值设定项,我们可以将
middleName
默认为
nil
,这样我们就不必在创建没有中间名的
人员时实际指定该初始值设定项)

然后你可以:

let person = Person(firstName: "Joe", lastName: "Blow")
print(person.fullName) // outputs "Joe Blow"
这样做的好处是,以后如果需要,我们可以在不破坏使用它的现有代码的情况下,向
Person
结构添加其他特性。例如,假设我们想添加处理包含多个中间名的非常长的名称的功能。我们可以用
middleNames
数组属性替换
middleNames
,然后执行如下操作:

struct Person {
    let firstName: String
    let middleNames: [String]
    let lastName: String

    init(firstName: String, middleName: String? = nil, lastName: String) {
        // continues to work exactly as before!
        self.firstName = firstName
        // map on an optional just means "run the closure if the value's not nil."
        // We could also use if let instead.
        self.middleNames = middleName.map { [$0] } ?? []
        self.lastName = lastName
    }

    init(firstName: String, middleNames: [String], lastName: String) {
        // new initializer that takes multiple middle names
        self.firstName = firstName
        self.middleNames = middleNames
        self.lastName = lastName
    }

    var fullName: String {
        let names = [self.firstName] + self.middleNames + [self.lastName]

        return names.join(separator: " ")
    }

    // and so that old code that called the `middleName` property continues to work:
    var middleName: String? { return self.middleNames.first }
}
简短答复:

如果让
进行测试,则使用
,而不是针对
nil
进行测试。这将“展开”变量,使其不再是可选的

而不是:

if foo != nil {
    doSomethingWith(foo) // WARNING: foo is optional!
}
这样做:

if let unwrappedFoo = foo {
    doSomethingWith(unwrappedFoo) // No warnings!
}
长答覆:

这里似乎有很多变量,其中许多是逻辑分组的。Person1FirstName、Person1MiddleName、Person1LastName、Person2FirstName、。。。人名。。。等等。您可以通过在结构中将它们组合在一起来简化此过程,如下所示:

struct Person {
    let firstName: String
    let middleName: String?
    let lastName: String
}
现在,我们可以添加一个方便的初始值设定项和一个方便的属性来生成全名:

struct Person {
    let firstName: String
    let middleName: String?
    let lastName: String

    init(firstName: String, middleName: String? = nil, lastName: String) {
        self.firstName = firstName
        self.middleName = middleName
        self.lastName = lastName
    }

    var fullName: String {
        if let middleName = self.middleName {
            return "\(self.firstName) \(middleName) \(self.lastName)"
        } else {
            return "\(self.firstName) \(self.lastName)"
        }
    }
}
(初始值设定项不是绝对必要的,因为编译器将自动为我们生成一个初始值设定项,但使用手动编写的初始值设定项,我们可以将
middleName
默认为
nil
,这样我们就不必在创建没有中间名的
人员时实际指定该初始值设定项)

然后你可以:

let person = Person(firstName: "Joe", lastName: "Blow")
print(person.fullName) // outputs "Joe Blow"
这样做的好处是,以后如果需要,我们可以在不破坏使用它的现有代码的情况下,向
Person
结构添加其他特性。例如,假设我们想添加处理包含多个中间名的非常长的名称的功能。我们可以用
middleNames
数组属性替换
middleNames
,然后执行如下操作:

struct Person {
    let firstName: String
    let middleNames: [String]
    let lastName: String

    init(firstName: String, middleName: String? = nil, lastName: String) {
        // continues to work exactly as before!
        self.firstName = firstName
        // map on an optional just means "run the closure if the value's not nil."
        // We could also use if let instead.
        self.middleNames = middleName.map { [$0] } ?? []
        self.lastName = lastName
    }

    init(firstName: String, middleNames: [String], lastName: String) {
        // new initializer that takes multiple middle names
        self.firstName = firstName
        self.middleNames = middleNames
        self.lastName = lastName
    }

    var fullName: String {
        let names = [self.firstName] + self.middleNames + [self.lastName]

        return names.join(separator: " ")
    }

    // and so that old code that called the `middleName` property continues to work:
    var middleName: String? { return self.middleNames.first }
}

对于这种情况,我将使用
??
。它允许您访问可选值或可选值(如果可选值当前为零)

let first:String =  "Steve"
let middle:String? = nil  // fixed this
let last:String =  "Jones"

let fullName = "\(first) \(middle ?? "") \(last)"
唯一的问题是,当这个人没有中间名时,你会得到两个空格。在这种情况下,更好的解决方案是:

let fullName = [first, middle ?? "", last].filter( { !$0.isEmpty} ).joined(separator: " ")

对于这种情况,我将使用
??
。它允许您访问可选值或可选值(如果可选值当前为零)

let first:String =  "Steve"
let middle:String? = nil  // fixed this
let last:String =  "Jones"

let fullName = "\(first) \(middle ?? "") \(last)"
唯一的问题是,当这个人没有中间名时,你会得到两个空格。在这种情况下,更好的解决方案是:

let fullName = [first, middle ?? "", last].filter( { !$0.isEmpty} ).joined(separator: " ")

您的问题之一是
让person2MiddleName:String?=“nil”
正在分配一个恰好包含字符串“nil”的非nil字符串。您想分配
…=nil
没有与之密切相关的引号:./rant/让我恼火的是“replicate”标签不一定是。2.5年前,当Swift回归2个主要版本时,有人问这个问题。示例中显示的一些方法甚至不再正确。死亡也是如此,因为它害怕重温旧话题,保持新鲜。唯一比必须弄清楚一个答案在互联网上有多流行更糟糕的事情就是没有任何流行的答案,因为主持人认为我们已经解决了这个问题/done rant/您的问题之一是
让person2MiddleName:String?=“nil”
正在分配一个恰好包含字符串“nil”的非nil字符串。您想分配
…=无