Return of split

I was using split(str,separator) and it returned SubString (I verified it with typeof) and wa using the result in later functions:

function instruct_processor(db::Dict,op::String)
    arr=split(op," ",limit=2)
    print("primer arr: ")
    println(typeof(arr))

and suddenly it returns a vector of substrings:

Vector{SubString{String}}

But what really intrigues me is that even though I was receiving an error

Because of this function:

function _long_adecuada(len::Integer,arr::Vector{SubString{String}})
    length(arr)!=len && throw(NumberArgsError())
   
end
ERROR: LoadError: MethodError: no method matching _long_adecuada(::Int64, ::Vector{SubString{String}})

Closest candidates are:
  _long_adecuada(::Integer, ::SubString{String})

The other functions that also received Substring did not show error:

This runs:

type or paste code here
```function insertField!(db::Dict,params::SubString{String})
    typeof(params)
    arr=split(params," ",limit=3)
    println(typeof(arr))
    println(length(arr))

For example? (Give minimal reproducer.)

1 Like

Please see the post Please read: make it easier to help you. It will make it easier to help with your questions.

1 Like

It’s hard to follow what you did and what works or not for you but the docstring for split says

Split str into an array of substrings

so focus on showing how to reproduce

I was using split(str,separator) and it returned SubString

and we can tell you whether there is some misunderstanding or you have found a bug.

A substring is like a view into a string, i.e., references into an existing string instead of allocating a new data structure. Many functions for splitting, matching etc on strings return substrings. Here is an example:

julia> txt = "Hi there"
"Hi there"

julia> sub = match(r"Hi", txt).match
"Hi"

julia> typeof(sub)
SubString{String}

julia> parent(sub)  # The underlying original string
"Hi there"

julia> split(txt, " ")
2-element Vector{SubString{String}}:
 "Hi"
 "there"

julia> parent.(split(txt, " "))
2-element Vector{String}:
 "Hi there"
 "Hi there"

Note that a SubString is not a String, i.e., a function with signature op::String will not work as expected:

julia> fun(op::String) = length(op)
fun (generic function with 1 method)

julia> fun(txt)
8

julia> fun(sub)
ERROR: MethodError: no method matching fun(::SubString{String})

If in doubt, leave out the type signature all together (would suggest that for beginners anyways) or use AbstractString instead which will match all of its subtypes:

julia> subtypes(AbstractString)
6-element Vector{Any}:
 Base.AnnotatedString
 Core.Compiler.LazyString
 LazyString
 String
 SubString
 SubstitutionString

I don’t see anything surprising there.

arr=split(op," ",limit=2)

gives you arr as a Vector{SubString{String}}.

Then arr[2] extracts one element from the vector which gives you a SubString{String}. When you send that single element to insertField! it complains because it requires a whole vector, not a single element.

The error says that insertField! expected a vector in its second argument (as per your type signature Vector{SubString{String}}), but was called with a SubString{String}, i.e., as single element of such a vector. Have not checked if this function actually needs to get passed a vector – but as split is called on params it most likely does not.

In any case, such a specific type signature usually restricts code unnecessarily. Consider AbstractVector{<:AbstractString} instead.