# String type that wraps an AbstractVector?

**URL:** <https://discourse.julialang.org/t/string-type-that-wraps-an-abstractvector/23901>\
**Category:** General Usage\
**Created:** [May 6, 2019, 9:28am UTC](https://discourse.julialang.org/t/string-type-that-wraps-an-abstractvector/23901 "2019-05-06T09:28:12Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![oschulz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oschulz/32/2998_2.png) [@oschulz](https://discourse.julialang.org/u/oschulz)\
**Post date:** [May 6, 2019, 9:28am UTC](https://discourse.julialang.org/t/string-type-that-wraps-an-abstractvector/23901/1 "2019-05-06T09:28:12Z")

</div>

Do we have a string type that wraps a (sub-)vector of bytes in some package? Something a bit safer than WeakRefString (so not pointer based)?

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [May 6, 2019, 1:30pm UTC](https://discourse.julialang.org/t/string-type-that-wraps-an-abstractvector/23901/2 "2019-05-06T13:30:37Z")

</div>

```julia
julia> String(rand(UInt8, 16))
"9#N\xab>x\xe2VD\xa2\x84-B\r\x15\xbd"

```

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [May 6, 2019, 3:26pm UTC](https://discourse.julialang.org/t/string-type-that-wraps-an-abstractvector/23901/3 "2019-05-06T15:26:12Z")

</div>

> [@StefanKarpinski](#):
>
> julia\> String(rand(UInt8, 16)) “9#N\xab\>x\xe2VD\xa2\x84-B\r\x15\xbd”

From the question, I would guess that the following behavior is not desired:

```julia
julia> a = rand(UInt8, 16);

julia> b = String(a)
"-\xfb\xe2d\x922]\xbc\xac\xc2\xf1\xa6\xa7F3;"

julia> a
0-element Array{UInt8,1}

```

but more something like a mutable String

```julia
mutable struct MutableString{A <: AbstractVector{<:UInt8}}
    v::A
end
```

---

<div class="post-metadata">

**Author:** ![bkamins](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bkamins/32/208538_2.png) [@bkamins](https://discourse.julialang.org/u/bkamins)\
**Post date:** [May 6, 2019, 3:45pm UTC](https://discourse.julialang.org/t/string-type-that-wraps-an-abstractvector/23901/4 "2019-05-06T15:45:32Z")

</div>

But the point is that `AbstractString` must not be mutable.

So you should rather write:

```julia
a = rand(UInt8, 16)
b = String(copy(a))

```

I think.

---

<div class="post-metadata">

**Author:** ![ExpandingMan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/expandingman/32/866_2.png) [@ExpandingMan](https://discourse.julialang.org/u/ExpandingMan)\
**Post date:** [May 6, 2019, 3:47pm UTC](https://discourse.julialang.org/t/string-type-that-wraps-an-abstractvector/23901/5 "2019-05-06T15:47:24Z")

</div>

Perhaps the orignal poster is looking for [codeunits](https://docs.julialang.org/en/v1/base/strings/#Base.codeunits).

---

<div class="post-metadata">

**Author:** ![oschulz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oschulz/32/2998_2.png) [@oschulz](https://discourse.julialang.org/u/oschulz)\
**Post date:** [May 6, 2019, 4:10pm UTC](https://discourse.julialang.org/t/string-type-that-wraps-an-abstractvector/23901/6 "2019-05-06T16:10:30Z")

</div>

> [@kristoffer.carlsson](#):
>
> From the question, I would guess that the following behavior is not desired:

Correct - this is for decoding some binary data with embedded strings (representing C++ type information, it’s ROOT files with custom streamers). I want to check what’s in these strings with minimum memory allocation and copies, so I’d like to just wrap a `SubArray` into something that implements an `AbstractString`. But the string may be passed around a bit (in a very limited fashion), so I’d like to avoid `WeakRefString`.

---

<div class="post-metadata">

**Author:** ![oschulz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oschulz/32/2998_2.png) [@oschulz](https://discourse.julialang.org/u/oschulz)\
**Post date:** [May 6, 2019, 4:14pm UTC](https://discourse.julialang.org/t/string-type-that-wraps-an-abstractvector/23901/7 "2019-05-06T16:14:14Z")

</div>

> [@ExpandingMan](#):
>
> Perhaps the orignal poster is looking for [codeunits](https://docs.julialang.org/en/v1/base/strings/#Base.codeunits)

I’m kinda looking for the reverse of `codeunits`: A copy-free way to wrap a sub-array into something string-like, without invalidating the original array.

---

<div class="post-metadata">

**Author:** ![ExpandingMan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/expandingman/32/866_2.png) [@ExpandingMan](https://discourse.julialang.org/u/ExpandingMan)\
**Post date:** [May 6, 2019, 5:06pm UTC](https://discourse.julialang.org/t/string-type-that-wraps-an-abstractvector/23901/8 "2019-05-06T17:06:15Z")

</div>

If I understand it correctly, this is deliberately disallowed because strings are treated as immutable. It would not be hard to create an `AbstractVector` with the behavior you are talking about.

Perhaps you could describe a bit about what you are trying to achieve? It seems to me that you could just go ahead and do whatever you like with a `Vector{UInt8}` and later call `String` on it. This is only inadequate if you need to repeatedly manipulate the string. Unicode gets a bit tricky, but again, it depends on what you are trying to do.

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [May 6, 2019, 7:40pm UTC](https://discourse.julialang.org/t/string-type-that-wraps-an-abstractvector/23901/9 "2019-05-06T19:40:49Z")

</div>

It should be possible to create a `StringView` type that takes a region of a byte array and wraps it to act like a string. One would want to reuse much of the code for `String` and `SubString{String}`, which is non-trivial, so the ideal way to do this might require a little refactoring of the code to make it possible to reuse or it might be easier to add `StringView` to Base and add it to the dispatch on the relevant methods.

---

<div class="post-metadata">

**Author:** ![oschulz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oschulz/32/2998_2.png) [@oschulz](https://discourse.julialang.org/u/oschulz)\
**Post date:** [May 7, 2019, 8:25am UTC](https://discourse.julialang.org/t/string-type-that-wraps-an-abstractvector/23901/10 "2019-05-07T08:25:08Z")

</div>

> [@ExpandingMan](#):
>
> If I understand it correctly, this is deliberately disallowed because strings are treated as immutable. It would not be hard to create an `AbstractVector` with the behavior you are talking about.

Sure, normally we definitely want Strings to be immutable. However, this is for a binary parsing application, and I’m checking the contents of strings imbedded in a buffer that will be destroyed afterwards. In the interest of performance, I don’t want to turn these embedded strings into actual `String`s, as that would result in unnecessary memory allocation.

`WeakRefString` has been created for scenarios like this, but in my case I don’t want something pointer based, at least not explicitly (I may use `UnsafeArray`s at a higher level). Of course it’s not hard to create something similar that is backed by an `AbstractVector{UInt8}` instead of a `Ptr{UInt8}` - I just didn’t wondered if someone had already done so in some package, to avoid duplication of work.

---

<div class="post-metadata">

**Author:** ![oschulz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oschulz/32/2998_2.png) [@oschulz](https://discourse.julialang.org/u/oschulz)\
**Post date:** [May 7, 2019, 8:34am UTC](https://discourse.julialang.org/t/string-type-that-wraps-an-abstractvector/23901/11 "2019-05-07T08:34:03Z")

</div>

> [@StefanKarpinski](#):
>
> It should be possible to create a `StringView` type that takes a region of a byte array

Kinda like that, yes. I just wondered if anybody had already done something like it. Basically something like

```julia
struct StringView{BV<:AbstractVector{<:UInt8}}
    data::BV
end

```

When used with an `Array` or `SubArray`, it would be completely safe (GC-wise), but immutability of the string’s content would not be guaranteed. When used with an [`UnsafeArray`](https://github.com/oschulz/UnsafeArrays.jl), it would be an allocation-free bitstype like `WeakRefString`, but still guarded by the automatic `GC.@preserve` of `UnsafeArrays.@uviews`.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [November 11, 2020, 5:18am UTC](https://discourse.julialang.org/t/string-type-that-wraps-an-abstractvector/23901/12 "2020-11-11T05:18:16Z")

</div>

> [@StefanKarpinski](#):
>
> It should be possible to create a `StringView` type that takes a region of a byte array and wraps it to act like a string. One would want to reuse much of the code for `String` and `SubString{String}` , which is non-trivial, so the ideal way to do this might require a little refactoring of the code to make it possible to reuse or it might be easier to add `StringView` to Base and add it to the dispatch on the relevant methods.

_Update:_ There is now a package for this: [GitHub - JuliaStrings/StringViews.jl: String-like views of arbitrary Julia byte arrays](https://github.com/JuliaStrings/StringViews.jl)

It has some code duplication with Base, but it would be possible to reduce this significantly by a tiny amount of refactoring in a future Julia version.

---

<div class="post-metadata">

**Author:** ![oschulz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oschulz/32/2998_2.png) [@oschulz](https://discourse.julialang.org/u/oschulz)\
**Post date:** [November 11, 2020, 9:13am UTC](https://discourse.julialang.org/t/string-type-that-wraps-an-abstractvector/23901/13 "2020-11-11T09:13:32Z")

</div>

Thanks a lot, @stevengj!
