Что такое discardableResult и как использовать этот атрибут?
Во время написания функций или методов в Swift мы в некоторых случаях хотим игнорировать возвращаемое значение, а в других – все же иметь возможность обработать его. Если попытаться вызвать метод, который возвращает значение, и никак его не обработать, получим предупреждение "Result of call to 'foo()' is unused".
Атрибут discardableResult позволяет убрать данное предупреждение. В случае правильного использования эта небольшая функция (о которой, тем не менее, стоит знать) улучшит чистоту вашего кода и позволит вам не использовать нижнее подчеркивание, чтобы игнорировать результат.
Перед написанием каждого метода хорошо подумайте, важно ли обрабатывать возвращаемое значение. В некоторых случаях лучше будет всё-таки заставить пользователя вашего метода хендлить его. Например, если есть необходимость сообщить важную информацию (о возникшей ошибке и пр.).
Source
#languageGuide #attributes #basic
Во время написания функций или методов в Swift мы в некоторых случаях хотим игнорировать возвращаемое значение, а в других – все же иметь возможность обработать его. Если попытаться вызвать метод, который возвращает значение, и никак его не обработать, получим предупреждение "Result of call to 'foo()' is unused".
Атрибут discardableResult позволяет убрать данное предупреждение. В случае правильного использования эта небольшая функция (о которой, тем не менее, стоит знать) улучшит чистоту вашего кода и позволит вам не использовать нижнее подчеркивание, чтобы игнорировать результат.
Перед написанием каждого метода хорошо подумайте, важно ли обрабатывать возвращаемое значение. В некоторых случаях лучше будет всё-таки заставить пользователя вашего метода хендлить его. Например, если есть необходимость сообщить важную информацию (о возникшей ошибке и пр.).
Source
#languageGuide #attributes #basic
Что такое параметры inout?
Когда мы передаем value типы в качестве аргументов в функцию, они статичны – менять их нельзя. Было бы удобно иметь возможность модифицировать данные значения. К счастью, у Swift для этого есть решение: ключевое слово inout, которое используется перед типом параметра в связке с '&' перед аргументом. Это позволит нам модифицировать значение внутри функции.
На самом деле, мы не модифицируем значением напрямую. Такое поведение называется "copy-in copy-out" или же "call by value result" и работает следующим образом:
1. Когда мы вызываем функцию, значение аргумента копируется.
2. Дальше внутри функции копия модифицируется.
3. По возращению функции Swift присваивает модифицированное значение оригинальному аргументу.
Параметры inout встречаются чаще, чем вам может показаться на первый взгляд. Например, оператор += использует inout для изменения строки, когда вы хотите добавить одну строку к другой.
Source
#languageGuide #inout #advanced
Когда мы передаем value типы в качестве аргументов в функцию, они статичны – менять их нельзя. Было бы удобно иметь возможность модифицировать данные значения. К счастью, у Swift для этого есть решение: ключевое слово inout, которое используется перед типом параметра в связке с '&' перед аргументом. Это позволит нам модифицировать значение внутри функции.
На самом деле, мы не модифицируем значением напрямую. Такое поведение называется "copy-in copy-out" или же "call by value result" и работает следующим образом:
1. Когда мы вызываем функцию, значение аргумента копируется.
2. Дальше внутри функции копия модифицируется.
3. По возращению функции Swift присваивает модифицированное значение оригинальному аргументу.
Параметры inout встречаются чаще, чем вам может показаться на первый взгляд. Например, оператор += использует inout для изменения строки, когда вы хотите добавить одну строку к другой.
Source
#languageGuide #inout #advanced
Как использовать ключевое слово rethrows?
По моему опыту, использовать это ключевое слово вы будете не слишком часто. Тем не менее, понимание принципов его работы поможет вам лучше определять случаи, когда rethrows будет полезным.
Ключевое слово rethrows используется, когда вы пишете функцию (назовем ее A), которая принимает другую функцию в качестве параметра (назовем ее B). Rethrows делает так, что если функция B выбрасывает ошибки, тогда и A будет выбрасывать ошибки. Если функция B не выбрасывает ошибки, тогда и A этого делать не будет.
Какое преимущество мы получаем? Rethrows позволяет убрать лишние try/catch в случаях, где они не нужны.
Возьмем стандартные 'map', 'filter', 'forEach' для массивов. Когда вы внутри замыкания помечаете что-то как try, Swift просит вас добавить try еще и для вызова "Call can throw but is not marked with 'try'". Если внутри замыкания ничего ошибку выбрасывать не будет, тогда и целый вызов помечать try не нужно.
Данное поведение во всех описанных выше методах реализовано с помощью rethrows.
Source
#languageGuide #rethrows #advanced
По моему опыту, использовать это ключевое слово вы будете не слишком часто. Тем не менее, понимание принципов его работы поможет вам лучше определять случаи, когда rethrows будет полезным.
Ключевое слово rethrows используется, когда вы пишете функцию (назовем ее A), которая принимает другую функцию в качестве параметра (назовем ее B). Rethrows делает так, что если функция B выбрасывает ошибки, тогда и A будет выбрасывать ошибки. Если функция B не выбрасывает ошибки, тогда и A этого делать не будет.
Какое преимущество мы получаем? Rethrows позволяет убрать лишние try/catch в случаях, где они не нужны.
Возьмем стандартные 'map', 'filter', 'forEach' для массивов. Когда вы внутри замыкания помечаете что-то как try, Swift просит вас добавить try еще и для вызова "Call can throw but is not marked with 'try'". Если внутри замыкания ничего ошибку выбрасывать не будет, тогда и целый вызов помечать try не нужно.
Данное поведение во всех описанных выше методах реализовано с помощью rethrows.
Source
#languageGuide #rethrows #advanced
Как добавить Pull-to-Refresh в UITableView или UICollectionView?
Swift предоставляет нам готовый функционал для этой цели, который реализован с помощью класса UIRefreshControl. Любой наследник UIScrollView имеет свойство refreshControl, а поскольку UITableView и UICollectionView как раз являются наследниками, нам достаточно присвоить экземпляр UIRefreshControl этому свойству.
Если вы хотите получить что-то более уникальное, например добавить свою анимацию, тогда можно обратить внимание на библиотеки как CRRefresh. Правда, по моему опыту, все они работают плохо и имеют те или иные проблемы.
Source
#languageGuide #UIRefreshControl #basic
Swift предоставляет нам готовый функционал для этой цели, который реализован с помощью класса UIRefreshControl. Любой наследник UIScrollView имеет свойство refreshControl, а поскольку UITableView и UICollectionView как раз являются наследниками, нам достаточно присвоить экземпляр UIRefreshControl этому свойству.
Если вы хотите получить что-то более уникальное, например добавить свою анимацию, тогда можно обратить внимание на библиотеки как CRRefresh. Правда, по моему опыту, все они работают плохо и имеют те или иные проблемы.
Source
#languageGuide #UIRefreshControl #basic
lazy теперь работает в локальном контексте (local context)
Используя ключевое слово lazy, мы можем реализовать свойство, начальное значение которого не вычисляется до первого использования. Начиная со Swift 5.5, можно использовать lazy внутри функций. На практике это позволит проводить оптимизацию, когда мы имеем какое-то условия if-else и не хотим проводить затратные вычисления на то, что нам не нужно.
Source
#languageGuide #lazy #intermediate
Используя ключевое слово lazy, мы можем реализовать свойство, начальное значение которого не вычисляется до первого использования. Начиная со Swift 5.5, можно использовать lazy внутри функций. На практике это позволит проводить оптимизацию, когда мы имеем какое-то условия if-else и не хотим проводить затратные вычисления на то, что нам не нужно.
Source
#languageGuide #lazy #intermediate
Различия между let и var
Когда в Swift нужно связать имя (например, "username" или "balance") со значением определенного типа (например, строка "Den" или число 96.23), используются константы и переменные.
Чтобы объявить константу, используем ключевое слово let, для переменной – var. Изменить значение константы после того, как мы ее объявили, нельзя, переменную же мы можем менять сколько угодно раз.
На скриншоте видим:
maxPasswordLenght – константа со значением 64, поскольку максимальная длина пароля в приложении фиксированная, и менять ее мы не будем;
currentPasswordLenght – переменная, потому что ее значение напрямую зависит от значения, которое пользователь вводит в текстовом поле.
Source
#languageGuide #properties #basic
Когда в Swift нужно связать имя (например, "username" или "balance") со значением определенного типа (например, строка "Den" или число 96.23), используются константы и переменные.
Чтобы объявить константу, используем ключевое слово let, для переменной – var. Изменить значение константы после того, как мы ее объявили, нельзя, переменную же мы можем менять сколько угодно раз.
На скриншоте видим:
maxPasswordLenght – константа со значением 64, поскольку максимальная длина пароля в приложении фиксированная, и менять ее мы не будем;
currentPasswordLenght – переменная, потому что ее значение напрямую зависит от значения, которое пользователь вводит в текстовом поле.
Source
#languageGuide #properties #basic