Help with my string type


Hi there,

I’m trying to implement a new string type consisting only of the characters [A-Z] and [0-9]:

abstract type AbstractMyString <: AbstractString end

struct MyString <: AbstractMyString
    MyString(str) = begin
        ismatch(CSE, str) || error("string contains illegal characters")
        return new(str)

const CSE = r"^.([A-Z]|[0-9])+$"

The problem I have is that I want MyString to work in functions that expect String. For example, I get the following error:

a = MyString("ASD1")
"Error showing value of type MyString:
ERROR: you must implement endof(MyString)

Which can be remedied by preventing the REPL from trying to print a, using a semi colon.

I thought that I could declare everything to be a subtype of AbstractString (as I cannot declare it to be subtype of String) and expect that everything that works with AbstractString to work with MyString. Where did I go wrong? How can I inherit the things that work with AbstractString?


You can defined Base.endof(str::MyString) = endof(str.str).


Yes, of course. But then I also have to define next(str::MyString), next(str::MyString, ::Int), etc. I thought I could save myself that.


AbstractString is an interface; meaning if you implement a few select methods, then you automatically hook into a bunch of methods defined on AbstractStrings. Granted, interfaces aren’t a totally concrete/fleshed out concept in julia; for example, it’d be nice if when you subtyped AbstractString, but didn’t implement the required methods, there was an immediate error somehow indicating the methods needed to fulfill the interface.

Of interest to you is that the AbstractString interface has actually changed between 0.6 and 0.7, with, IMO, 0.7 having a much cleaner interface and definitely better docs to explain everything. Take a look here to get a better idea of what’s expected of AbstractString subtypes.


Also see discussions about inheriting interfaces:


Thanks, this helps a lot. However, I’d still need to know what needs forwarding.