Golang中如何解决不能将string类型用作*string类型的问题

Golang中如何解决不能将string类型用作*string类型的问题

package main

import (
	"html/template"
	"os"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"database/sql"
	"strconv"
)

var tmplSrc = `
{{range $i, $a := .Title}}
  Title: {{$a}}-{{.DD}}-{{.FF}}
  {{range $article := index $.Article $i}}
	Article: {{$article}}.
  {{end}}
{{end}}`

func dbConn() (db *sql.DB) {
	dbDriver := "mysql"
	dbUser := "root"
	dbPass := ""
	dbName := "ask"
	db, err := sql.Open(dbDriver, dbUser+":"+dbPass+"@/"+dbName)
	if err != nil {
		panic(err.Error())
	}
	return db
}

type a struct {
	Title   []b
	Title1  []c
	Article [][]string
}
type b struct{
	DD   string
	FF int
}
type c struct{
	CC string
	EE string
}

type d struct{
	DD string
	
}

func main() {
	xx:=b{}
	Title:=[]b{}
	
	yy:=c{}
	Title1:=[]c{}

	Article:=[][]string{}
	
	for i:=0; i<=2; i++{
		xx.DD=strconv.Itoa(i)+"a"
		xx.FF=i
		Title=append(Title,xx)
		
		Title1=nil
		for ii:=0; ii<=2; ii++{
			yy.CC=strconv.Itoa(ii)+"b"
			yy.EE=strconv.Itoa(ii)+"c"
			Title1=append(Title1,yy)
		}
		fmt.Println(Title1)
		Article=append(Article,Title1)	
	}

	var data = &a{
		Title: Title,
		Article: Article,
	}
	fmt.Println(data)
	tmpl := template.Must(template.New("test").Parse(tmplSrc))
	tmpl.Execute(os.Stdout, data)
}

感谢


更多关于Golang中如何解决不能将string类型用作*string类型的问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html

9 回复

下次我会表达得更清楚些…

更多关于Golang中如何解决不能将string类型用作*string类型的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


很抱歉,先生。

我遇到了这个错误

无法将 Title1(类型 []c)用作类型 []string 在 append 中使用

在这一行:

Article=append(Article,Title1)	

请帮忙

对于字符串切片,你可以追加一个字符串,或者使用省略号语法来追加另一个字符串切片的所有元素。你的示例介于这两种有效变体之间,因此需要确定 Title1 应该是一个字符串,还是你实际想表达的是 Title1...

这里有一篇关于切片的好文章:https://blog.golang.org/go-slices-usage-and-internals

有个问题想请教……

我不太确定你的帖子具体想表达什么……

你现在的代码在 play.golang.org 上是无法运行的,因为它需要外部依赖。

请尝试将其简化为一个最小可复现示例,很多时候在这个过程中你就能自己找到问题的解决方案。

将问题精简到核心部分后,你可以在这里添加简化后的代码,或者提供一个 playground 链接。

引用 n_oandasan:

我遇到了这个错误

cannot use Title1 (type []c) as type []string in append

而你甚至没有在原始帖子中提到这一点,反而选择了一个暗示你在某处混淆了字符串和字符串指针的标题…

请尝试以更聪明的方式提问。

不要只是把代码扔到论坛上,就以为每个人都知道你在做什么。尤其不要假设每个人都愿意下载可能与你的问题无关的库(比如这里的 MySQL 驱动程序)。

另外,请实际提供问题描述,而不仅仅是代码和"谢谢"…

感谢您的回复,但我认为 Title1… 并不是解决方案。以下是我试图实现的输出结果。

标题:{0a 0}-0a-0

文章:{0b 0c} .

文章:{1b 1c}

文章:{2b 2c}

标题:{1a 1}-1a-1

文章:{0b 0c} .

文章:{1b 1c}

文章:{2b 2c}

标题:{2a 2}-2a-2

文章:{0b 0c} .

文章:{1b 1c}

文章:{2b 2c}

感谢您的建议,聪明的人给出的简短建议却非常实用。我是这样实现的:

	type a struct {
		Title   []b
		Title1  []b
		Article [][]b
	}
	type b struct{
		DD   string
		FF int
	}
	type c struct{
		CC string
		EE string
	}

	type d struct{
		DD string
		
	}

	func main() {
		xx:=b{}
		Title:=[]b{}
		
		yy:=b{}
		Title1:=[]b{}

		Article:=[][]b{}
		
		for i:=0; i<=2; i++{
			xx.DD=strconv.Itoa(i)+"a"
			xx.FF=i
			Title=append(Title,xx)
			
			Title1=nil
			for ii:=0; ii<=2; ii++{
				yy.DD=strconv.Itoa(ii)
				Title1=append(Title1,yy)
			}

			fmt.Println(Title1)
			Article=append(Article,Title1)
		}
			

		var data = &a{
			Title: Title,
			Article: Article,
		}
		fmt.Println(data)
		tmpl := template.Must(template.New("test").Parse(tmplSrc))
		tmpl.Execute(os.Stdout, data)
	}

结果…这正是我一直在寻找的。谢谢

标题:{0a 0}-0a-0

-文章:{0 0}。

-文章:{1 0}。

-文章:{2 0}。

标题:{1a 1}-1a-1

-文章:{0 0}。

-文章:{1 0}。

-文章:{2 0}。

标题:{2a 2}-2a-2

-文章:{0 0}。

-文章:{1 0}。

-文章:{2 0}。

在Go语言中,当遇到不能将string类型用作*string类型的问题时,通常是因为代码中试图将字符串值直接赋值给指针类型变量,或者函数参数要求指针类型但传递了值类型。以下是针对您代码中可能出现的这类问题的分析和解决方案。

问题分析

在您的代码中,虽然没有直接显示*string相关的错误,但在模板处理和数据传递时,如果结构体字段定义为指针类型但传递了字符串值,就会出现此类问题。

解决方案

1. 使用地址操作符(&)创建字符串指针

package main

import (
    "fmt"
)

func main() {
    // 错误示例:直接将字符串赋值给字符串指针
    // var strPtr *string = "hello" // 这会导致编译错误
    
    // 正确方法1:先定义字符串变量,再取地址
    str := "hello"
    strPtr := &str
    fmt.Printf("Value: %s, Pointer: %p\n", *strPtr, strPtr)
    
    // 正确方法2:使用new函数创建字符串指针
    strPtr2 := new(string)
    *strPtr2 = "world"
    fmt.Printf("Value: %s, Pointer: %p\n", *strPtr2, strPtr2)
}

2. 修改结构体定义以正确处理指针类型

package main

import (
    "html/template"
    "os"
    "fmt"
    "strconv"
)

// 修改结构体以支持指针字段
type b struct{
    DD   *string  // 改为指针类型
    FF   int
}

type c struct{
    CC *string  // 改为指针类型
    EE *string  // 改为指针类型
}

func main() {
    xx := b{}
    Title := []b{}
    
    Article := [][]string{}
    
    for i := 0; i <= 2; i++ {
        // 为字符串字段创建指针
        dd := strconv.Itoa(i) + "a"
        xx.DD = &dd
        xx.FF = i
        Title = append(Title, xx)
        
        articleRow := []string{}
        for ii := 0; ii <= 2; ii++ {
            articleItem := strconv.Itoa(ii) + "b"
            articleRow = append(articleRow, articleItem)
        }
        Article = append(Article, articleRow)
    }

    var data = &a{
        Title: Title,
        Article: Article,
    }
    
    fmt.Println(data)
    
    // 在模板中使用指针字段时需要解引用
    var tmplSrc = `
{{range $i, $a := .Title}}
  Title: {{$a.DD}}-{{.FF}}  {{/* 这里DD是指针,模板会自动解引用 */}}
  {{range $article := index $.Article $i}}
    Article: {{$article}}.
  {{end}}
{{end}}`
    
    tmpl := template.Must(template.New("test").Parse(tmplSrc))
    tmpl.Execute(os.Stdout, data)
}

3. 处理函数参数中的字符串指针

package main

import (
    "fmt"
)

// 函数接受字符串指针参数
func processStringPtr(s *string) {
    if s != nil {
        fmt.Printf("Processing: %s\n", *s)
    } else {
        fmt.Println("Received nil pointer")
    }
}

func main() {
    // 正确传递字符串指针
    str := "example"
    processStringPtr(&str)
    
    // 或者使用new创建
    strPtr := new(string)
    *strPtr = "another example"
    processStringPtr(strPtr)
    
    // 也可以传递nil
    processStringPtr(nil)
}

4. 在数据库操作中处理可能为NULL的字符串字段

package main

import (
    "database/sql"
    "fmt"
    _ "github.com/go-sql-driver/mysql"
)

type User struct {
    ID    int
    Name  *string  // 使用指针来处理可能为NULL的数据库字段
    Email *string
}

func main() {
    db, err := sql.Open("mysql", "user:pass@/dbname")
    if err != nil {
        panic(err.Error())
    }
    defer db.Close()
    
    var user User
    err = db.QueryRow("SELECT id, name, email FROM users WHERE id = ?", 1).Scan(
        &user.ID,
        &user.Name,  // 直接扫描到字符串指针
        &user.Email,
    )
    
    if err != nil {
        panic(err.Error())
    }
    
    // 安全地使用可能为nil的指针字段
    if user.Name != nil {
        fmt.Printf("User name: %s\n", *user.Name)
    } else {
        fmt.Println("User name is NULL")
    }
}

关键要点

  1. 使用&操作符获取字符串变量的地址来创建*string
  2. 使用new(string)创建新的字符串指针
  3. 在访问指针前总是检查是否为nil以避免运行时panic
  4. 模板引擎通常能够自动处理指针的解引用
  5. 数据库操作中使用指针类型来处理可能为NULL的字段

这些方法应该能解决您遇到的字符串类型与字符串指针类型不匹配的问题。

回到顶部