【问题标题】:How can I model GeoJSON geometries in Fantom?如何在 Fantom 中为 GeoJSON 几何建模?
【发布时间】:2015-12-18 14:44:48
【问题描述】:

我从几何的这个基本抽象类开始:

@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 类?

【问题讨论】:

    标签: fantom afbedsheet


    【解决方案1】:

    对于序列化,您需要一个名为 make() 的 it 块 ctor。但这并不能阻止您定义自己的 ctor。我会将这两个 ctor 分开,作为分离关注点的一种方式。

    对于简单的数据类型,我通常会将字段值作为 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 会从参数中计算出来。

    还请注意,您自己的 ctor 可以命名为任何名称,但按照惯例,它们以 makeXXXX() 开头。

    然后使用IoC 自动构建GeoPoint,请执行以下操作:

    point := (GeoPoint) registry.autobuild(GeoPoint#, [[1d, 2d]])
    

    然后将使用makeWithCoors() ctor。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-14
      • 2016-05-19
      • 2021-11-11
      • 2015-11-21
      • 2019-11-13
      • 1970-01-01
      • 1970-01-01
      • 2015-07-29
      相关资源
      最近更新 更多