string - 将字符串与指向字符串的指针作为参数传递给函数时,时间复杂度有什么区别?
问题描述
假设我有一个字符串 s。
s := "helloworld"
现在,我的问题是,如果 s 有“n”个字节,那么如果我将 s 传递给一个函数,而不是将 &s 传递给一个函数然后访问字符串的第 i 个字节,那么相对于“n”的时间复杂度是多少。
如果将 &s 传递给函数并访问字符串的第 i 个字节需要 O(1) 时间,那么当我将 s 传递给函数然后访问字符串的第 i 个字节时是否需要 O(n) 时间(因为整个字符串将被复制)?
我试过了,发现复制一个字符串确实会改变指向它的指针。希望能更清楚地说明这一点。
func main() {
str := "helloworld"
fmt.Println("string pointer 1:", &str)
printStringPointer(str)
}
func printStringPointer(s string) {
fmt.Println("string pointer 2:", &s)
}
输出:
string pointer 1: 0xc000010200
string pointer 2: 0xc000010210
解决方案
Go 中的字符串类似于切片,它们只是一个包含指向底层数据的指针和长度的细描述符。
您可以在reflect.StringHeader类型中看到这一点:
type StringHeader struct {
Data uintptr
Len int
}
将字符串传递给函数时,会复制标头,但不会复制底层数据。我们可以更改您的示例以打印 的值Data
,表明它指向内存中的相同地址:操场链接:
func main() {
str := "helloworld"
fmt.Println("string pointer 1: ", &str)
fmt.Println("string Data 1: ", (*reflect.StringHeader)(unsafe.Pointer(&str)).Data)
printStringPointer(str)
}
func printStringPointer(s string) {
fmt.Println("string pointer 2: ", &s)
fmt.Println("string Data 2: ", (*reflect.StringHeader)(unsafe.Pointer(&s)).Data)
}
输出:
string pointer 1: 0xc000010200
string Data 1: 4970654
string pointer 2: 0xc000010210
string Data 2: 4970654
传递字符串是常量时间(复制头部),底层数据不被复制。
推荐阅读
- reactjs - 通过反应获取 cookie
- regex - 按组匹配的正则表达式
- java - Apache Kafka Streams API 或生产者/消费者 API
- nginx - 虚拟机上 NGINX 中的“未知“mage_run_code”变量错误”
- python-3.x - 获取函数的模块(独立定义)
- django - 在 Django 查询集中按月份和性别分组
- xamarin.forms - 登录并导航到其他页面时应用程序崩溃
- go - 如何检查 NATS 请求是否被取消
- python - python - for循环输入多个数据帧以发挥作用
- angular - Angular 2+ 浏览器历史和返回按钮