我如何在 Fantom 中建模 GeoJSON 几何图形?
How can I model GeoJSON geometries in Fantom?
我从几何学的基本摘要 class 开始:
@Serializable
abstract const class Geometry {
const Str type
new make( Str type, |This| f ) {
this.type = type
f(this)
}
}
然后我扩展了这个抽象class来模拟一个点:
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 classes 吗?
对于序列化,您需要一个名为 make()
的 it-block ctor。但这并不妨碍您定义自己的 ctors。我会把两个 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()
构造函数,您可以使用 makeWithCoors()
构造函数 - 如下所示:
point1 := GeoPoint([1d, 2d]) // or
point2 := GeoPoint.makeWithCoors([1d, 2d])
请注意,您不必为构造函数命名,因为 Fantom 会根据参数计算出来。
另请注意,您自己的 ctors 可以任意命名,但按照惯例,它们以 makeXXXX()
.
开头
然后用 IoC 自动构建一个 GeoPoint
这样做:
point := (GeoPoint) registry.autobuild(GeoPoint#, [[1d, 2d]])
然后将使用 makeWithCoors()
构造函数。
我从几何学的基本摘要 class 开始:
@Serializable
abstract const class Geometry {
const Str type
new make( Str type, |This| f ) {
this.type = type
f(this)
}
}
然后我扩展了这个抽象class来模拟一个点:
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 classes 吗?
对于序列化,您需要一个名为 make()
的 it-block ctor。但这并不妨碍您定义自己的 ctors。我会把两个 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()
构造函数,您可以使用 makeWithCoors()
构造函数 - 如下所示:
point1 := GeoPoint([1d, 2d]) // or
point2 := GeoPoint.makeWithCoors([1d, 2d])
请注意,您不必为构造函数命名,因为 Fantom 会根据参数计算出来。
另请注意,您自己的 ctors 可以任意命名,但按照惯例,它们以 makeXXXX()
.
然后用 IoC 自动构建一个 GeoPoint
这样做:
point := (GeoPoint) registry.autobuild(GeoPoint#, [[1d, 2d]])
然后将使用 makeWithCoors()
构造函数。