Julia: how to avoid boilerplate code when structs sharing attributes

universal_amateur

It happens quite regularly that different structs (EDIT: types) should share some attributes. If i got it right as a beginner: In Julia, you can extend abtract types, but they may not have any attributes. Concrete types (=structs) are not extendable. So, is there a way to avoid code repetition (for attributes name and weight) like in the given example?

abstract type GameObj end

struct Gem <: GameObj
  name::String
  weight::Int64
  worth::Int64
end

struct Medicine <: GameObj
  name::String
  weight::Int64
  healing_power::Int64
end

g = Gem("diamond", 13, 23000)
m = Medicine("cough syrup", 37, 222)

I tried to put the shared attributes into an extra struct, like in the following example. Advantage: No code repetition. Disadvantages: calling constructors and getting attributes (g.attributes.weight) is inconvenient.

abstract type GameObj end

struct GameObjAttr
  name::String
  weight::Int64
end

struct Gem <: GameObj
  attributes::GameObjAttr
  worth::Int64
end

struct Medicine <: GameObj
  attritbutes::GameObjAttr
  healing_power::Int64
end

g = Gem(GameObjAttr("diamond", 13), 23000)
m = Medicine(GameObjAttr("cough syrup", 37), 222)

The third example uses inner constructors, now the constructor calls are more easy to read and write, but now we have some code repetition in the inner constructors. Plus: Getting the shared attributes is still inconvenient:

abstract type GameObj end

struct GameObjAttr
  name::String
  weight::Int64
end

struct Gem <: GameObj
  attributes::GameObjAttr
  worth::Int64
  Gem(name::String, weight::Int64, worth::Int64) = new(GameObjAttr(name, weight), worth)
end

struct Medicine <: GameObj
  attributes::GameObjAttr
  healing_power::Int64
  Medicine(name::String, weight::Int64, healing_power::Int64) = new(GameObjAttr(name, weight), healing_power)
end

g = Gem("diamond", 13, 23000)
m = Medicine("cough syrup", 37, 222)

Is there another, better way to avoid this kind of code repetition? (Besides that: is it necessary to declare types inside the inner constructor, or can we leave that?)

Thanks in advance.

Korsbo

You can use Julia's metaprogramming abilities for this.

abstract type GameObj end

type_fields = Dict(
                   :Gem => (:worth, Int64),
                   :Medicine => (:healing_power, Int64)
                  )


for name in keys(type_fields)
  @eval(
    struct $name <: GameObj
      name::String
      weight::Int64
      $(type_fields[name][1])::$(type_fields[name][2])
    end
  )
end

g = Gem("diamond", 13, 23000)
m = Medicine("cough syrup", 37, 222)

This is similiar to you copy-pasting the code but it allows you to do it programmatically. Note that we use $ to interpolate external values into the expression which is being executed in the loop.

Edit (based on question in comments):

If you want to be able to add an arbitrary number of fields for the different types you can make a minor modification to the above code:

abstract type GameObj end

type_fields = Dict(
                   :Gem => ((:worth, Int64),
                            (:something_else, Any)),
                   :Medicine => ((:healing_power, Int64),)
                  )


for name in keys(type_fields)
  @eval(
    struct $name <: GameObj
      name::String
      weight::Int64
      $(map( x -> :($(x[1])::$(x[2])), type_fields[name])...)
    end
  )
end

g = Gem("diamond", 13, 23000, :hello)
m = Medicine("cough syrup", 37, 222)

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

How to remove the boilerplate code when using q in node.js

分類Dev

How to avoid globals in EEPROM structs for system settings?

分類Dev

How do I avoid absolute pathnames in my code when using Git?

分類Dev

How to represent two structs that are really similar without code redundancy?

分類Dev

minifying boilerplate code on C++ template code

分類Dev

How to avoid wrapping code in a promise callback?

分類Dev

How to avoid code duplication for const versions of functions

分類Dev

How to avoid repeating the following replace code?

分類Dev

How to display the command and avoid code injection

分類Dev

Julia: Modifying the same field in an array of Mutable Structs

分類Dev

How to download CS:GO demo from match sharing code

分類Dev

How to avoid coupling when using useReducer?

分類Dev

How to insert django form field attributes into HTML code?

分類Dev

How do i parallelize julia code without changing the eventual output?

分類Dev

How to avoid copying data between Java and Native C++ Code

分類Dev

How to avoid room foreign key error - constraint failed (code 787)

分類Dev

How to avoid code duplication in Github Actions; are there some kind of loops in yaml?

分類Dev

How to avoid writing same code over again in UIViewController in Swift?

分類Dev

How do I avoid duplication of code using AASM?

分類Dev

How to change the display attributes of SPECIFIC tabs when using tabPanel in navbarPage

分類Dev

How to reduce boilerplate currently necessary for serialization

分類Dev

How to remove boilerplate in vector of tuple initialization?

分類Dev

How should a boilerplate LESS framework be customised?

分類Dev

How can I reduce boilerplate from this function?

分類Dev

How to add, subtract, etc. two structs element-by-element when they have the same fields

分類Dev

Sharing code between python files

分類Dev

How to avoid hardware compability problems when shopping for a laptop to run Linux on?

分類Dev

How to avoid slow collapse when using bootstrap collapse and div in a table

分類Dev

How to avoid duplicate key error in swift when iterating over a dictionary

Related 関連記事

  1. 1

    How to remove the boilerplate code when using q in node.js

  2. 2

    How to avoid globals in EEPROM structs for system settings?

  3. 3

    How do I avoid absolute pathnames in my code when using Git?

  4. 4

    How to represent two structs that are really similar without code redundancy?

  5. 5

    minifying boilerplate code on C++ template code

  6. 6

    How to avoid wrapping code in a promise callback?

  7. 7

    How to avoid code duplication for const versions of functions

  8. 8

    How to avoid repeating the following replace code?

  9. 9

    How to display the command and avoid code injection

  10. 10

    Julia: Modifying the same field in an array of Mutable Structs

  11. 11

    How to download CS:GO demo from match sharing code

  12. 12

    How to avoid coupling when using useReducer?

  13. 13

    How to insert django form field attributes into HTML code?

  14. 14

    How do i parallelize julia code without changing the eventual output?

  15. 15

    How to avoid copying data between Java and Native C++ Code

  16. 16

    How to avoid room foreign key error - constraint failed (code 787)

  17. 17

    How to avoid code duplication in Github Actions; are there some kind of loops in yaml?

  18. 18

    How to avoid writing same code over again in UIViewController in Swift?

  19. 19

    How do I avoid duplication of code using AASM?

  20. 20

    How to change the display attributes of SPECIFIC tabs when using tabPanel in navbarPage

  21. 21

    How to reduce boilerplate currently necessary for serialization

  22. 22

    How to remove boilerplate in vector of tuple initialization?

  23. 23

    How should a boilerplate LESS framework be customised?

  24. 24

    How can I reduce boilerplate from this function?

  25. 25

    How to add, subtract, etc. two structs element-by-element when they have the same fields

  26. 26

    Sharing code between python files

  27. 27

    How to avoid hardware compability problems when shopping for a laptop to run Linux on?

  28. 28

    How to avoid slow collapse when using bootstrap collapse and div in a table

  29. 29

    How to avoid duplicate key error in swift when iterating over a dictionary

ホットタグ

アーカイブ