golang源码阅读-strings

1. 判断一个字符串的前缀是否为另一个字符串

hasStrPrefix := strings.HasPrefix("jin tian tian qi hao", "jin tian")

  源码:

func HasPrefix(s, prefix string) bool {
	return len(s) >= len(prefix) && s[0:len(prefix)] == prefix
}

     s字符串的长度大于等于prefix字符串的长度 并且 s字符串截取0到 len(prefix) 是否为prefix

2. 判断一个字符串是否包含另一个字符串

hasContains := strings.Contains("jin tian tian qi hao", "tian qi")

  源码:

func Contains(s, substr string) bool {
	return Index(s, substr) >= 0
}

 substr字符串在s字符串位置是否大于0

3. 返回字符串s中有几个不重复的sep子串。

count := strings.Count("jin", "")

 源码:

 

func Count(s, substr string) int {
	// special case
	//如果子字符串为空
	if len(substr) == 0 {
		//返回s长度加1
		//If substr is an empty string, Count returns 1 + the number of Unicode code points in s.
		return utf8.RuneCountInString(s) + 1
	}
	//子字符串等于1时
	if len(substr) == 1 {
		//Go 语言编译指示 https://segmentfault.com/a/1190000016743220
		return bytealg.CountString(s, substr[0])
	}
	n := 0
	//开始循环
	for {
		//substr在s中位置
		i := Index(s, substr)
		//如果i==-1 就是s内没有substr时 直接返回n,第一次执行n是0
		if i == -1 {
			return n
		}
		//执行到这里说明s包含substr,n加1
		n++
		//s去掉substr部分 再次循环
		s = s[i+len(substr):]
	}
}

 

4. 子串sep在字符串s中第一次出现的位置,不存在则返回-1。

i := strings.Index("jin tian tian qi hao", "qi")

源码:

func Index(s, substr string) int {
	//获取substr长度
	n := len(substr)
	switch {
	case n == 0:
		//substr长度为0返回0
		return 0
	case n == 1:
		//如果是1时
		return IndexByte(s, substr[0])
	case n == len(s):
		//长度相等时
		//两个字符串相等 返回0
		if substr == s {
			return 0
		}
		return -1
	case n > len(s):
		return -1
	case n <= bytealg.MaxLen:
		// Use brute force when s and substr both are small
		//当s和substr都很小的时候使用蛮力
		//小于等于64
		if len(s) <= bytealg.MaxBruteForce {
			return bytealg.IndexString(s, substr)
		}
		//获取子字符串 第一个字符
		c0 := substr[0]
		//第二个字符
		c1 := substr[1]
		i := 0
		//如果s包含substr, substr的第一个字符 c0 一定在s为 0 到  len(s) - n + 1 之间
		t := len(s) - n + 1
		//失败次数
		fails := 0
		for i < t {
			//如果开始字符不相等
			if s[i] != c0 {
				// IndexByte is faster than bytealg.IndexString, so use it as long as
				// we're not getting lots of false positives.
				//查找首次位置
				o := IndexByte(s[i:t], c0)
				if o < 0 {
					//没有返回 -1
					return -1
				}
				//位置后移 出现的位置
				i += o
			}

			//判断下是否相等
			if s[i+1] == c1 && s[i:i+n] == substr {
				return i
			}
			//加1
			fails++
			i++
			// Switch to bytealg.IndexString when IndexByte produces too many false positives.
			//失败次数达到一定次数 换个方法
			if fails > bytealg.Cutover(i) {
				r := bytealg.IndexString(s[i:], substr)
				if r >= 0 {
					return r + i
				}
				return -1
			}
		}
		return -1
	}

	//类似上面
	c0 := substr[0]
	c1 := substr[1]
	i := 0
	t := len(s) - n + 1
	fails := 0
	for i < t {
		if s[i] != c0 {
			o := IndexByte(s[i:t], c0)
			if o < 0 {
				return -1
			}
			i += o
		}
		if s[i+1] == c1 && s[i:i+n] == substr {
			return i
		}
		i++
		fails++
		if fails >= 4+i>>4 && i < t {
			// See comment in ../bytes/bytes_generic.go.
			j := indexRabinKarp(s[i:], substr)
			if j < 0 {
				return -1
			}
			return i + j
		}
	}
	return -1
}

5. 返回s中每个单词的首字母都改为标题格式的字符串拷贝。

title := strings.Title("jin tian tian qi hao")

源码:

func Title(s string) string {
	// Use a closure here to remember state.
	// Hackish but effective. Depends on Map scanning in order and calling
	// the closure once per rune.
	prev := ' '
	//Map 说明: 将s的每一个unicode码值r都替换为mapping(r),返回这些新码值组成的字符串拷贝。如果mapping返回一个负值,
	// 将会丢弃该码值而不会被替换。(返回值中对应位置将没有码值)


	return Map(
		func(r rune) rune {
			//如果前一个字符串分界
			if isSeparator(prev) {
				//当前r更新为prev
				prev = r
				//转换为大写
				return unicode.ToTitle(r)
			}
			//返回原r
			prev = r
			return r
		},
		s)
}

 

你可能感兴趣的:(golang)