struct MyStruct {
@ArrayOfNonOptionalElements var arr: [SomeNonOptionalType]
}
где @ArrayOfNonOptionalElements — это propertyWrapper.
Итак, как обеспечить необязательность для типа внутри? Возможно ли это вообще? 🙄
Я имею в виду, как реализовать оболочку свойства таким образом, чтобы тип элемента массива был необязательным.
Обновление:
Ну, похоже, мой вопрос никто не понял 😣
Я хочу, чтобы компилятор не ставил вопросительный знак внутри квадратных скобок 😃
Обновление 2:
Скопирую/вставлю сюда один из моих комментариев из-под поста, чтобы все могли его увидеть:
Я пишу свойство @Compact для безопасного декодирования массива. Итак результат гарантированно не будет содержать нулей. Это свойство обертка может работать с любыми типами массивов. Так что это скорее просто своего рода перфекционистского вызова 🙂
@DávidPásztor Я пишу propertyWrapper "@Compact" для безопасного декодирования массива. Таким образом, результат гарантированно не будет содержать нулей. Эта оболочка свойства может работать с любыми типами массивов. Так что это скорее своего рода перфекционистский вызов 🙂
если ваш массив определен как [SomeNonOptionalType], он уже гарантированно не будет иметь нулей. Иметь ноль было бы [SomeNonOptionalType?]. Так что именно вы пытаетесь предотвратить?
Я думаю, ОП хочет, чтобы wrappedValue как [T] для оболочки свойств был прикреплен @ArrayOfNonOptionalElements var arr: [T?]. Не уверен, потому что сам вопрос говорит об обратном, но их ответ предполагает это.
Чтобы прояснить ваш вопрос, можете ли вы показать попытку и описать, почему она не работает?
Пост обновлен ✅
В Swift нет «противоположного» типа Optional, поэтому я не думаю, что вы сможете добиться такой проверки времени компиляции.
@JoakimDanielson Похоже на идею для предложения Swift Evolution 😃
Вы пытаетесь гарантировать, что разработчик случайно не наберет [SomeNonOptionalType?] вместо [SomeNonOptionalType], требуя от того же разработчика аннотировать строку @ArrayOfNonOptionalElements? Почему? Компилятор уже помогает вам без какой-либо специальной обертки. Если массив случайно объявлен разрешающим необязательные параметры, то для каждого доступа к массиву потребуется код для обработки необязательного, а не необязательного.
@HangarRash Я снова обновил пост. Пожалуйста, посмотрите 🙂
Я правильно понимаю, что @Compact будет содержать ненулевые значения, даже если закодированные данные содержат нули?
@Roman Ваши обновления не отвечают на мои вопросы. Какую предполагаемую выгоду вы ожидаете получить, пытаясь заставить разработчика добавить @ArrayOfNonOptionalElements к строке кода на случай, если тот же разработчик случайно добавит ? к остальной части объявления массива? Как я уже сказал, компилятор уже помогает вам, не нуждаясь в каких-либо аннотациях.
@Cy-4AH ✅ В этом вся суть 😃
@HangarRash Возможно, ты прав. Ну... похоже, это всё равно невозможно 😅
@ Cy-4AH На самом деле даже больше. Он также «отфильтрует» любые ошибки декодирования. Таким образом, ошибка в одном элементе массива декодирования больше не приведет к сбою всего вашего приложения 😅 Проблемный элемент будет просто пропущен.
@Роман, твои недавние вопросы кажутся XY-проблемами . Вместо того, чтобы чрезмерно упрощать реальную проблему, которую вы пытаетесь решить, стоило бы задать вопрос о реальной проблеме в форме минимального воспроизводимого примера. Вопрос «Как мне декодировать массив JSON таким образом, чтобы, если один элемент не может быть декодирован, он не терпел неудачу во всем декодировании, а просто пропускал этот элемент», будет совершенно другим вопросом, чем тот, который вы в конечном итоге задали. , но, похоже, проблема, которую вы на самом деле пытаетесь решить.
@Dávid Pásztor «Как мне декодировать массив JSON таким образом, чтобы, если один элемент не может быть декодирован, он не терпел неудачу во всем декодировании, а просто пропускал этот элемент» - это не мой вопрос, это не проблема. Я знаю, как это сделать. На самом деле я уже это сделал, и все работает отлично 😃 Проблема, которую я сейчас пытаюсь решить, заключается именно в том, о чем я спросил: «Я хочу, чтобы компилятор не ставил вопросительный знак внутри квадратных скобок»
Я не могу придумать, как это сделать, и вполне логично, что вы не можете. По аналогии, это было бы похоже на наличие некоторого func i<T>(_ value: T) -> T { value }, но ограничение его настолько T произвольным не может быть Int. Какой вред был бы, если бы ограничения не существовало? Обобщенные значения связаны с ограничением значений протоколами, что, в свою очередь, дает этим обобщенным значениям больше возможностей (поскольку у вас есть доступ к требованиям протокола). Если есть что-то, что необязательный может сделать, а необязательный не может, вам следует отразить это в ограничении протокола.
Вам нужно написать свой макрос вместо propertyWrapper. Плохо, что ваш вопрос закрыт и вы признали, что это невозможно. Идея хорошая 👍
@ Cy-4AH Cy-4AH Я закончил свою работу и открыл ее исходный код. Так что теперь каждый может воспользоваться результатом (или даже внести свой вклад 😉). Надеюсь, вам это будет полезно 🙂 gitlab.com/roman.kisliaченко/decodable-kit



Итак, как обеспечить необязательность для типа внутри? Возможно ли это вообще? 🙄
Нет. В Swift нет способа выразить «нет» в системе типов. (Появится новый ~Copyable, но он не означает «не копируемый». Это означает «устраняет неявное предположение о копируемости».)
Я пишу свойство @Compact для безопасного декодирования массива. Таким образом, результат гарантированно не будет содержать нулей. Эта оболочка свойства может работать с любыми типами массивов.
Это не совсем точно. Опциональные параметры являются декодируемыми, если их оболочка является декодируемой. Таким образом, справедливо следующее:
try JSONDecoder().decode([Int?].self, from: Data("[1]".utf8)) // [Optional(1)]
Это говорит о том, что ваш @Compact все еще может возвращать массив опционалов. И если он может вернуть опциональные параметры, он может вернуть nil. Система типов должна быть в состоянии доказать во время компиляции, что это невозможно, и, судя по тому, что вы описали, это возможно, вы просто «обещаете», что этого не произойдет. И система типов не позволит вам избежать наказания за это, как и ее работа.
Но даже если бы вы действительно могли пообещать то, что обещаете, система типов Swift не сможет это выразить.
Да, я думаю, что уже нашел хорошее компромиссное решение. Вместо того, чтобы бороться с системой, я буду использовать ее, чтобы получить еще больше функциональности для моей обертки. Я просто немного изменю семантику, переименовав «@Compact» в «@Exemptify». И не будет отфильтровывать "нули" в случае, если разработчик явно поставил "?" внутри "[]". В этом случае он будет только отфильтровывать ошибки декодирования. Если нет "?" внутри "[]" тогда "nils" сами по себе становятся ошибками декодирования и автоматически отфильтровываются. Ощущение очень последовательного поведения 🙂
Я закончил свою работу и открыл исходный код. Буду признателен, если вы посмотрите. Надеюсь, вам будет интересно 🙂 gitlab.com/roman.kisliaченко/decodable-kit
Лично я не большой поклонник оберток свойств для подобных вещей. Если у вас это работает, это здорово, но я считаю их слишком хрупкими для сложных систем. Ошибки легко выбросить, но трудно с ними справиться таким образом. Я немного рассказываю об этом и о том, как я предпочитаю это делать, здесь: youtube.com/watch?v=-k_vipGhugQ&t=340
Что на самом деле делает ваша оболочка свойств? Вы просто пытаетесь добиться того, чтобы свойство не могло быть необязательным? Для этого вам не нужна оболочка свойств. Или вы на самом деле пытаетесь создать оболочку свойства, которая делает что-то полезное, но не может работать с опциями?