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

Сейчас я изучаю непрозрачные типы, все еще немного сбивающие с толку. Я пробовал следующее:

protocol Animal {
    func introduce()
}

struct Dog: Animal {
    func introduce() {
        print("Dog")
    }
}

struct Cat: Animal {
    func introduce() {
        print("Cat")
    }
}

func random() -> some Animal {
    let value = [true, false].randomElement()!
    return value ? Cat() : Dog()
}

И в строке возврата random я получаю следующую ошибку

Result values in '? :' expression have mismatching types 'Cat' and 'Dog'

Итак, насколько я понимаю, так же, как и в Generics, компилятор должен иметь возможность решать во время компиляции, каков конкретный возвращаемый тип функции.

Я прав? Если да, то разве это сообщение не сбивает с толку, поскольку обе структуры реализуют Animal? И если я ошибаюсь, что означает это сообщение об ошибке?

Большое спасибо

РЕДАКТИРОВАТЬ: я пытаюсь понять, а не заставить это работать :)


person Yotam    schedule 28.03.2021    source источник
comment
stackoverflow.com/questions/56433665 /   -  person Sh_Khan    schedule 28.03.2021


Ответы (1)


Подумайте об этом: каков тип значения выражения? Cat() : Dog() Это не животное. А для тройки нужен один тип, а у вас либо кошка, либо собака. Вывод типа не позволит понять, что вы можете стереть эти два разных типа обратно в какой-то общий тип, даже если это возможно сделать.

person Shadowrun    schedule 28.03.2021
comment
Но если я удалю some, он скомпилируется. Это потому, что в этом случае swift возвращает экзистенциальный контейнер, а не конкретный тип? - person Yotam; 28.03.2021
comment
@Yotam прочитайте вопрос, указанный в комментарии выше. - person Joakim Danielson; 28.03.2021
comment
Да. Если вы возвращаете животное, это означает, что оно может вывести животное для троичного выражения. Тогда обе вещи могут быть одинаковыми, тернар счастлив. Но это не относится к некоторым животным, потому что это означает, что вы возвращаете, скажем, настоящую кошку или настоящую собаку. Звонящий может принять это за какое-то животное, но это ниже по течению. Некоторое животное не является типом, так что это не может объединить два тернарных типа. - person Shadowrun; 28.03.2021
comment
@JoakimDanielson Я сделал это недостаточно ясно. Во всяком случае, я думаю, что понял. Спасибо - person Yotam; 28.03.2021