Как я могу моделировать геометрию GeoJSON в Fantom?
Я начал с этого базового абстрактного класса для геометрии:
@Serializable
abstract const class Geometry {
const Str type
new make( Str type, |This| f ) {
this.type = type
f(this)
}
}
Затем я расширил этот абстрактный класс для моделирования точки:
const class GeoPoint : Geometry {
const Decimal[] coordinates
new make( |This| f ) : super( "Point", f ) { }
Decimal? longitude() { coordinates.size >= 1 ? coordinates[ 0 ] : null }
Decimal? latitude() { coordinates.size >= 2 ? coordinates[ 1 ] : null }
Decimal? altitude() { coordinates.size >= 3 ? coordinates[ 2 ] : null }
}
Это компилируется нормально и работает нормально в простом сценарии, но если я пытаюсь использовать через IoC, я получаю это сообщение об ошибке:
[err] [afBedSheet] afIoc::IocErr - Field myPod::GeoPoint.coordinates was not set by ctor sys::Void make(|sys::This->sys::Void| f)
Causes:
afIoc::IocErr - Field myPod::GeoPoint.coordinates was not set by ctor sys::Void make(|sys::This->sys::Void| f)
sys::FieldNotSetErr - myPod::GeoPoint.coordinates
IoC Operation Trace:
[ 1] Autobuilding 'GeoPoint'
[ 2] Creating 'GeoPoint' via ctor autobuild
[ 3] Instantiating myPod::GeoPoint via Void make(|This->Void| f)...
Stack Trace:
afIoc::IocErr : Field myPod::GeoPoint.coordinates was not set by ctor sys::Void make(|sys::This->sys::Void| f)
Я предполагаю, что это потому, что конструктор имеет другой параметр, кроме |This| f
, Есть ли лучший способ написать классы Geology и GeoPoint, пожалуйста?
1 ответ
Для сериализации вам понадобится it-block ctor make()
, Но это не мешает вам определять свои собственные ctors. Я бы держал эти две группы отдельно, чтобы разделить проблемы.
Для простого типа данных я обычно передаю значения полей в качестве параметров ctor.
Это оставит объекты, выглядящие так:
@Serializable
abstract const class Geometry {
const Str type
// for serialisation
new make(|This| f) {
f(this)
}
new makeWithType(Str type) {
this.type = type
}
}
@Serializable
const class GeoPoint : Geometry {
const Decimal[] coordinates
// for serialisation
new make(|This| f) : super.make(f) { }
new makeWithCoors(Decimal[] coordinates) : super.makeWithType("Point") {
this.coordinates = coordinates
}
}
Сериализация Fantom будет использовать make()
Ctor и вы можете использовать makeWithCoors()
ctor - вот так:
point1 := GeoPoint([1d, 2d]) // or
point2 := GeoPoint.makeWithCoors([1d, 2d])
Обратите внимание, что вам не нужно называть ctor, так как Fantom определит его по аргументам.
Также обратите внимание, что ваши собственные ctors могут быть названы как угодно, но по соглашению они начинаются с makeXXXX()
,
Чтобы затем автоматически построить GeoPoint
с IoC сделайте это:
point := (GeoPoint) registry.autobuild(GeoPoint#, [[1d, 2d]])
что бы затем использовать makeWithCoors()
т е р.