Hi,
I am writing functions that expect string arguments containing only 'X'
, 'Y'
and 'Z'
, such as "XYZXYZZYX"
. Rather than checking in each functions that the arguments are matched by a certain regex, it seems only natural to create a dedicated type, say XYZString
. Then functions like
function f(s::XYZString) begin
...
end
are sure to operate on a good, “parsable” argument s
when called as
s = XYZString("XYZYYXZ")
f(s)
and I can remove validation and defensive coding from them.
So far I am failing to understand the proper way to construct this type.
- Can it be a simple type?
Is there valid code in the vein of:
type XYZString String # meaning XYZString is just a string under the hood
XYZString(s::AbstractString)::XYZString = ...
-
Should it be some kind of type alias?
-
Should it be a struct with an embedded string type implementing all the methods of the
AbstractString
interface?
Like so:
struct XYZString <: AbstractString
s::String
function XYZString(s::string)::XYZString
if Set(s) ⊈ Set('X','Y','Z') throw(DomainError, "bad string") end
new(s)
end
end
# many methods on XYZString to implement AbstractString, but which ones!?
# ...
It looks so verbose I cannot believe it is the right answer, plus I don’t know which methods are required and which are not, the docs are unclear to me, and finally I am bother by the necessity to embed a name value in a whole struct when all we need is just a string.
- How would this discussion extends for
Vector{Char}
instead of string?
Namely, expecting arrays like['X', 'Y', 'Z', 'Y']
instead of strings like"XYZY"
. Would it be easier?
It is similar to this question, though I find the answers do not help for beginner in Julia like me.