Я начал изучать Go после игры со структурной типизацией на других языках, таких как Scala и OCaml, и я пытаюсь отобразить некоторые из них идиоматические методы между языками. Рассмотрим следующие типыСтруктурная типизация и полиморфизм в Go - Написание метода, который может работать на двух типах с одинаковыми полями
type CoordinatePoint struct {
x int
y int
// Other methods and fields that aren't relevant
}
type CartesianPoint struct {
x int
y int
// Other methods and fields that aren't relevant
}
Скажем, мы хотели бы написать метод, который работает на обоих этих типов, чтобы вычислить их полярных координат представления, func ConvertXYToPolar(point XYPoint) PolarPoint
. Если типы CartesianPoint
и CoordinatePoint
определяют методы получения и установки для полей x
и y
, мы можем определить XYPoint
как общий интерфейс с этими методами, что позволяет нам работать с обоими типами, но, поскольку это означает, интерфейсы не могут объявлять поля, а только методы.
Исходя из этого, у меня есть несколько вопросов:
- Что такое идиоматических способ обработки этого в Go?
- Можно ли это сделать без изменения существующих типов?
- Можем ли мы сохранить безопасность типа, то есть избегать определения
ConvertXYToPolar
без использования пустого типа интерфейса в качестве параметра и преобразования вручную? - Если интерфейсы и неявное удовлетворение интерфейсов являются первичными инструментами для полиморфизма в Go, является ли запрет полей в ограничениях интерфейсов?
- Являются ли методы getter/setter, обычно определяемые на structs, чтобы обойти это ограничение?
- Есть ли веская причина для принятия конструктивного решения не для поддержки полей в определениях интерфейсов?
Я считаю простоту встроенных типов, неявным удовлетворения интерфейса и интерфейс на основе полиморфизма быть очень простым и привлекательным сочетанием методов содействия повторного использования кода и ремонтопригодности, но запрещающее поле в определениях интерфейса делает Гоу возможности структурной типизации несколько ограничены с моей точки зрения. Я пропустил простое решение?
За исключением того, что этот метод не поддерживает полиморфизм и поэтому не удовлетворяет потребностям, изложенным в вопросе, который должен передать либо координатный указатель, либо CartesianPoint для функции, которая вычисляет PolarPoint. Вы не могли, учитывая это решение, написать ConvertXYToPolar как «func (Point) PolarPoint» и принять, например, CartesianPoint. – burfl
@burfl Ответ не был завершен. Я думаю, что ваша озабоченность сейчас решена. –
Хорошие дополнения. Мне очень нравится этот подход. Я бы использовал интерфейс с getX(), setX(), getY() и setY(), но это менее элегантно, чем ваше решение. +1 – burfl