Обратите внимание, что разница между этими двумя строками:
options: TopicOption.allCases, // no error
activeOptions: self.$optionsStore.topicOptions // error
заключается в том, что первая строка не содержит Binding
. Обычно массив подтипов может быть назначен переменной типа массива супертипов. Это не верно для Binding<[Subtype]>
и Binding<[Supertype]>
.
Это потому, что Binding
нужно не только получить значение, которое вы передаете. Это также устанавливает это. Вспомните общий сценарий передачи Binding<String>
в TextField
. Значение Binding
изменится, когда пользователь введет текст, верно?
OptionsView
объявляет Binding<[OptionCompatible]>
. Это говорит о том, что он может добавить какой-то тип OptionCompatible
в массив. Но вы передаете это [TopicOptions]
! Например, если OptionsView
хочет добавить LevelOption
в массив, он не может!
Вы можете сказать: «Но я уверен, что мой OptionsView
будет добавлять только объекты правильного типа! " Ну, способ сказать это компилятору - сделать OptionsView
generi c:
struct OptionsView<OptionType: OptionCompatible>: View {
let options: [OptionType]
@Binding var activeOptions: [OptionType]
}