Урок 14. Опциональные типы

5 Февраля 2023

Задача 14.1 📚

Кроме массива вам потребуется свойство, которое будет хранить значение пользователя. Для извлечения опционального значения используйте опцинальную привязку, либо значение по умолчанию.

Создайте числовой массив. Добавьте в массив значение, которое внесет пользователь (рассматриваем только положительные значения), только в том случае если оно меньше минимального значения этого массива. 

				
					var numbers = [14, 29, 8, 17]
let userNumber = 6

if let minNumber = numbers.min() {
    if userNumber < minNumber {
        numbers.append(userNumber)
    }
}
				
			

Так как в массив мы добавляем значение он должен быть переменной. Так же для решения нам потребуется еще одно свойство userNumber, которое хранит значение, внесенное пользователем. 

Сперва мы извлекаем опционал из минимального значения массива, используя для этого опциональную привязку. То есть новому свойству minNumber пытаемся присвоить опциональное значение. Если это нам удается мы делаем проверку и добавление в массив этого элемента. 

Если вы создали дополнительное свойство для минимального значения, это не будет считаться ошибкой. 

Здесь так  же, для извлечения, отлично подойдет значение по умолчанию:

				
					var numbers = [14, 29, 8, 17]
let userNumber = 6

if userNumber < numbers.min() ?? 0 {
    numbers.append(userNumber)
}

				
			

Этот код выглядит лаконичней. И опять же если вы создали доп свойство для минимального значения, то это не ошибка. 

А вот если вы выполнили задание следующим образом:

				
					var numbers = [14, 29, 8, 17]
let userNumber = 6

if userNumber < numbers.min()! {
    numbers.append(userNumber)
}
				
			

Это будет считаться ошибкой. Никакого принудительного извлечения в вашем коде быть не должно! 

Следующий код так же будет считаться ошибкой:

				
					var numbers = [14, 29, 8, 17]
let userNumber = 6

if numbers.min() != nil {
    if userNumber < numbers.min()! {
        numbers.append(userNumber)
    }
}
				
			

Да, здесь есть проверка на nil, но по факту это все то же опасное принудительное извлечение. Это не желательный способ!

Задача 14.2 📚

Начните с перебора по словарю, при помощи цикла for in, для наполнения общей суммы, берете значение из словаря и прибавляете к новому свойству. 

Для решения этой задачи вам потребуется следующий словарь:

				
					var salaries = ["Tim": 4000, "Bob": 5500, "Taylor": 3000]
				
			

Сперва найдите общую сумму значений данного словаря. Далее обновите значение по ключу “Bob” на 6000, используя метод updateValue(). Определите разницу на которую изменилось значение, и прибавьте эту разницу к общей сумме. 

Используйте только пройденные концепции.

				
					var salaries = ["Tim": 4000, "Bob": 5500, "Taylor": 3000]

var total = 0

for (_, selary) in salaries {
    total += selary
}

let promotion = salaries.updateValue(6000, forKey: "Bob") // 1
let remainder = (salaries["Bob"] ?? 0) - (promotion ?? 0) // 2

total += remainder
				
			

Так как мы меняем значение словаря, то этот словарь должен быть переменной. То же самое с свойством total, мы его изменяем. 

Далее запускаем перебор по словарю и прибавляем каждое значение к свойству total. Обратите внимание что ключ после ключевого слова for заменен на нижнее подчеркивание, а все потому что мы его не используем, потому и не прописываем. Наш главный девиз: “Ничего лишнего в коде быть не должно!”

Либо можно было делать перебор с одним свойством:

				
					for selary in salaries {
    total += selary.value
}
				
			

Это тоже будет отличным решением.

(1) Метод updateValue, обновляет значение по ключу, и в тоже время возвращает нам старое значение, мы можем этим воспользоваться. 

(2) Присваиваем новому свойству результат вычислений. Берем новое значение по ключу, оно опциональное, поэтому мы извлекаем опциональное значение при помощи двойного вопросительного знака и задаем значение по умолчанию 0. Затем из нового значения вычитаем старое, которое получили от метода updateValue.

Для каждого результата лучше создать отдельное свойство, так легче работать с данными.

Если вы выполнили все как в решении выше, но извлекли опциональное значение принудительно, то это будет считаться грубой ошибкой:

				
					var salaries = ["Tim": 4000, "Bob": 5500, "Taylor": 3000]

var total = 0

for (_, selary) in salaries {
    total += selary
}

let promotion = salaries.updateValue(6000, forKey: "Bob")
let remainder = salaries["Bob"]! - promotion!

total += remainder
				
			

Принудительное извлечение, в реальной разработке, в 99% плохо, вы такой подход будете часто встречать на YouTube и в других источниках, их часто используют что бы не тратить время на мягкое извлечение, а сосредоточится на конкретной концепции. 

Так же не лучшим решением будут захардкоженные данные (внесенные ручками значения, не привязанные к свойствам):

				
					var salaries = ["Tim": 4000, "Bob": 5500, "Taylor": 3000]

var total = 0

for (_, selary) in salaries {
    total += selary
}

let promotion = salaries.updateValue(6000, forKey: "Bob")
let remainder = 6000 - 5500

total += remainder

				
			

Свойство remainder всегда будет рассчитывать одно и то же значение, и если вы где то в коде измените начальное значение по ключу “Bob”, то вам придется постоянно возвращаться к вашему коду, и править все руками. Всегда старайтесь избегать просто значений, они обязательно должны от чего то зависеть. 

На самом деле это задание можно было решить и по другому, нет серебряной пули, которая вам точно скажет что нужно так и не иначе. 

Давайте рассмотрим еще одно не совсем корректное решение:

				
					var salaries = ["Tim": 4000, "Bob": 5500, "Taylor": 3000]
var summ = 0

for n in salaries {
	summ += n.value
}

let changeK = 6000
let update = salaries.updateValue(changeK, forKey: "Bob")

if var update = update {
	update = changeK - update
	summ += update
}

				
			

Здесь есть несколько замечаний, во первых мы не называем свойства в одну букву, свойство должно быть емким и понятным, никаких сокращений и уж тем более букв, такое имя может запутать, что бы вникнуть в логику нужно будет приложить усилие. Здесь очень хорошо подойдет имя selary. 

Второй момент на который следует обратить внимание, так это на то что при использовании опциональной привязки для извлечения опционального значения, необходимо использовать константы, здесь же есть лишние действия, от которых можно избавиться:

				
					if let update = update {
	summ += changeK - update
}

				
			
Нам не нужно переменная, мы можем все сделать на прямую. И последнее замечание к такому коду, это имя свойства summ, в английском такого слова нет, всегда сверяйтесь с переводчиком.

Поддержите наш проект, и помогите изменить подход к обучению!

Address List

Social Networks

Поддержите наш проект, и помогите изменить подход к обучению!

Поддержите наш проект, и помогите изменить подход к обучению!

Развивайся вместе с нами