#go #inheritance #interface
#Вперед #наследование #интерфейс
Вопрос:
Как человеку, который освоился в мире Python, мне недавно пришлось улучшить производительность API. Из личных интересов я хотел переделать все это с помощью Golang.
Одна часть реализации состоит из преобразования координат в геометрию GeoJSON и создания из них коллекции.
Поскольку для некоторых конечных точек требуется создание разных геометрий из одних и тех же координат, я хотел абстрагировать все, что связано с построением геометрий. Мой подход заключался в передаче функции, которая возвращает экземпляр интерфейса методу, который преобразует координаты.
// This is what I want to create
type Collection struct {
Geometries *[]Geometry
}
type Geometry interface {}
type Point struct {
Coordinates [1][2]float64
}
type Polygon struct {
Coordinates [1][5][2]float64
}
type GeometryConstructor func(float64, float64) *Geometry
// This is the method to convert
func DataFrameToCollection(data DataFrame, constructor GeometryConstructor) *Collection {
geometries := make([]Geometry, data.Len())
for i := 0; i < data.Len(); i {
geometries[i] = *constructor(data.Lat.ItemAt(i), data.Lng.ItemAt(i))
}
return amp;Collection{
Geometries: amp;geometries,
}
}
// This is a constructor method I want to pass
func PointFromLatLng(lat, lng float64) *Point {
return amp;Point{
Coordinates: [1][2]float64{
{lng, lat},
},
}
}
Поэтому я мог бы в конечном итоге просто подключить соответствующий метод конструктора следующим образом
func main() {
// data := ...
collection := DataFrameToCollection(amp;data, PointFromLatLng)
}
Проблема в том, что методы конструктора не возвращают экземпляр интерфейса.
Каков наиболее подходящий идиоматический способ решения этой проблемы (избегая операторов if / switch-case)?
Ответ №1:
Вы можете использовать встроенные адаптеры:
collection := DataFrameToCollection(amp;data, func(lat,lon float64) Geometry { return PointFromLatLng(lat,lon) } )