nim string

string difinition

lib/system.nim

    NimStringDesc {.compilerproc, final.} = object of TGenericSeq
      data: UncheckedArray[char]
    NimString = ptr NimStringDesc

lib/system/sysstr

strings are dynamically resized, have a length field
and are zero-terminated, so they can be casted to C
strings easily
we don’t use refcounts because that’s a behaviour
the programmer may not want

cstring and nim string conversation

var cstr:cstring 
var nimstr = $cstr
cstr = cstr.cstring  
``

##  string and sequence conversation  
``` nim
var s: seq[char] = @['A', 'b', 'C']
var t: string = cast[string](s)
import sequtils
var s = toSeq("abc".items)

proc toString(str: seq[char]): string =
  result = newStringOfCap(len(str))
  for ch in str:
    add(result, ch)

echo toString(s)

optimizing-for-nim-optimizing-string-handling

optimizing-for-nim-optimizing-string-handling


var s = "abc"
shallow(s) # mark 's' as shallow string
var x = s  # now might not copy the string!

Usage of shallow is always safe once you know the string won’t be modified anymore, similar to Ruby’s freeze.

The compiler optimizes string case statements: A hashing scheme is used for them if several different string constants are used. So code like this is reasonably efficient:

case normalize(k.key)
of "name": c.name = v
of "displayname": c.displayName = v
of "version": c.version = v
of "os": c.oses = split(v, {';'})
of "cpu": c.cpus = split(v, {';'})
of "authors": c.authors = split(v, {';'})
of "description": c.description = v
of "app":
  case normalize(v)
  of "console": c.app = appConsole
  of "gui": c.app = appGUI
  else: quit(errorStr(p, "expected: console or gui"))
of "license": c.license = UnixToNativePath(k.value)
else: quit(errorStr(p, "unknown variable: " & k.key))

string interpolation

using strformat module

import strformat
let msg = "hello"
echo fmt"{msg}\n"

using strutils module

import strutils
let str = "$#, $#, $#"
let interp = str % ["One", "Two", "Three"]