Skip to content

proposal: strings: add Reverse function #63683

@cuishuang

Description

@cuishuang

This proposal aims to simplify string reversal tasks in Go by including a dedicated method in the standard library strings package.

Reversing a string is a very common operation in many situations. Currently, Go does not provide it in the standard library. Gophers need to write extra code to implement this functionality themselves in every project.

Adding a Reverse() method in the strings package could significantly improve productivity and code readability when string reversal is needed. The method would take a string as input and return its reversed version without mutating the original. It is a frequently needed low-level string operation suitable for including in the standard library.

The implementation could use a slice swap approach like:

func Reverse(s string) string {
  runes := []rune(s)
  for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
    runes[i], runes[j] = runes[j], runes[i]
  }
  return string(runes)
}

Or consider performance and perform different processing based on string length

package strings

import (
 "sync"
 "unicode/utf8"
)

const threshold = 100  // This value needs to be discussed

var runePool = sync.Pool{
 New: func() interface{} {
  return make([]rune, 0, threshold)
 },
}

// Reverse returns the inverted string of s.
// Implemented through slice inversion, directly 
// inverting bytes for small strings.
// Using rune array inversion for large strings.
func Reverse(s string) string {
 if len(s) == 0 {
  return ""
 }

 if len(s) < threshold {
  // Short string direct inversion
  bytes := []byte(s)
  for i, j := 0, len(bytes)-1; i < j; i, j = i+1, j-1 {
   bytes[i], bytes[j] = bytes[j], bytes[i]
  }
  return string(bytes)
 }

 // Inverting Long Strings with a Run Array
 runes := runePool.Get().([]rune)
 runes = runes[:0]
 runes = append(runes, []rune(s)...)
 
 for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
  runes[i], runes[j] = runes[j], runes[i]
 }
 s = string(runes)
 runePool.Put(runes)
 return s
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions