Быстрое необязательное присваивание, разбирайте ноль / пустую строку - PullRequest
0 голосов
/ 24 мая 2018

Я пытаюсь решить проблему назначения строк в Swift: здесь у нас есть структура:

struct Student {
    var name: String
    var id: String
    var mentor: String?
    var grade: String?
}

И мы хотим разобрать ее в строку, что-то вроде:

if (mentor != nil && grade != nil) {
    return "Student info: name:" + name + " id:" + id + " mentor:" + mentor! + " grade:" + grade! + "."
} else if (mentor != nil) {
    return "Student info: name:" + name + " id:" + id + " mentor:" + mentor! + "."
} else if (grade != nil) { 
    return "Student info: name:" + name + " id:" + id + " grade:" + grade! + "."
} else {
    return "Student info: name:" + name + " id:" + id + "."
}

Я новичок в Swift, приведенный выше код основан на опыте других языков, мне интересно, есть ли еще более краткий способ добиться этого в Swift?Как и в случае с необязательным toString (), если он равен nil, вернуть пустую строку ""?

Ответы [ 2 ]

0 голосов
/ 24 мая 2018

Ответ Александра хорош, и он хорошо использует карту функций более высокого порядка (), но это может быть немного сложнее, если вы только начинаете.Вы могли бы немного упростить свой код с разумным использованием if let «необязательного связывания»:

var result = "Student info: name:" + name + " id:" + id
if let mentor = mentor {
  result += " mentor:" + mentor
}
if let grade = grade {
  result += " grade:" + grade
}
result += "."

return result

или переписать, чтобы избежать оператора +:

var result = "Student info: name:\(name) id:\(id)"
if let mentor = mentor {
  result.append(" mentor:\(mentor)")
}
if let grade = grade {
  result.append(" grade:\(grade)")
}
result.append(".")

return result
0 голосов
/ 24 мая 2018

Вот улучшения, которые я бы сделал:

Во-первых, вы должны удалить ненужные скобки вокруг предикатов if.Вы можете привыкнуть к ним из других C-подобных языков, но в Swift они просто шумовые.

Во-вторых, вам следует заменить конкатенацию строк (+) интерполяцией.У него гораздо более быстрое время компиляции (вывод типа оператора существенно замедляет компилятор), и скоро (с переработкой интерполяции строк) будет иметь лучшую производительность во время выполнения (без избыточного выделения строк).

Далее я бы использовал Optional.map, чтобы построить все части предложения, которые являются необязательными.Затем я бы по умолчанию присвоил им пустую строку, если они nil.

Затем я бы взял все сегменты строки и соединил их вместе с пробелом в качестве разделителя:

struct Student {
    var name: String
    var id: String
    var mentor: String?
    var grade: String?
}

extension Student: CustomStringConvertible {
    var description: String {
        let start = "Student info:"
        let nameSegment = "name: \(self.name)"
        let idSegment = "id: \(self.id)"
        let mentorSegment = self.mentor.map { "mentor: \($0)" } ?? ""
        let gradeSegment = self.grade.map { "grade: \($0)" } ?? ""
        return [start, nameSegment, idSegment, mentorSegment, gradeSegment].joined(separator: " ")
    }
}

print(Student(name: "Bob", id: "id123", mentor: "Mr. Mentor", grade: "123"))
// => Student info: name: Bob id: id123 mentor: Mr. Mentor grade: 123
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...