1

Coming from a Scala background, a typical way of storing complex long lived immutable objects (like a big GeoJson MultiPolygon loaded from a file) would be the following:

// in Helpers.scala
package helpers

object Helpers {
  val landPolygons = loadFromGeoJsonFile("land-polygons.geojson")
  val mountains = loadFromGeoJsonFile("mountains.geojson")
}

// and anywhere else in the app
import helpers.Helpers._

def myAwesomeFunc() = {
  val myPoint = Point(23.0, 56.0)
  val distFromLand = myPoint.distance(landPolygons)
  val distFromMountains = myPoint.distance(mountains)
}

What would be the most adequate pattern to achieve the same functionality in Rust? The idea is that the values landPolygons and mountains have to be computed only once, and then available to use from anywhere in the whole application.

When trying to use a const or static declaration, the compiler outputs the following error:

error[E0015]: calls in constants are limited to struct and enum constructors
  --> src/utils.rs:30:32
   |
30 | const LAND_POLYGONS: GeoJson = include_str!("resources/land.geojson").parse::<GeoJson>().unwrap();
   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
note: a limited form of compile-time function evaluation is available on a nightly compiler via `const fn`
  --> src/utils.rs:30:32
   |
30 | const LAND_POLYGONS: GeoJson = include_str!("resources/land.geojson").parse::<GeoJson>().unwrap();
   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Jivan
  • 21,522
  • 15
  • 80
  • 131
  • You could use [lazy_static](https://docs.rs/lazy_static/1.0.0/lazy_static/) perhaps. But it really depends on what problems you are trying to solve - a "complex long-lived immutable object" isn't itself a problem, and global variables are an anti-pattern, that can usually be avoided. So it would be useful to know what are the problems that need to be solved. – Peter Hall May 14 '18 at 17:39
  • Well, basically, the exact problem stated in the question. As in, how to declare a static complex object like the one mentioned in the example, so that it can be further used from anywhere in the application, with no need to compute it again. Looks like `lazy_static` is the way to go. – Jivan May 14 '18 at 17:44
  • 1
    I believe your question is answered by the answers of [How do I create a global, mutable singleton?](https://stackoverflow.com/q/27791532/155423) and [How can you make a safe static singleton in Rust?](https://stackoverflow.com/q/27221504/155423). If you disagree, please [edit] your question to explain the differences. Otherwise, we can mark this question as already answered. – Shepmaster May 14 '18 at 17:55
  • 1
    @Shepmaster looks like the second one (safe static singleton) is answering it perfectly. – Jivan May 14 '18 at 17:57
  • 1
    Food for thought: how does Scala handle your code in the presence of multiple threads? – Shepmaster May 14 '18 at 17:59

0 Answers0