如何向ichiban/prolog的Query函数传递参数?
向ichiban/prolog的Query函数传递参数的正确方式
向ichiban/prolog库的Query函数传参,有两种常用实现方式:基于Prolog的format/2语法构建动态查询,或是使用**复合项(compound terms)**构造查询——后者在安全性和稳定性上更优。
动态查询示例
通过字符串插值将参数直接嵌入查询语句:
package main import ( "fmt" "log" "github.com/ichiban/prolog" ) func main() { // 初始化Prolog解释器 m := prolog.NewMachine() // 向数据库添加事实 err := m.Exec(`parent(john, mary).`) if err != nil { log.Fatal(err) } // 定义查询参数 parent := "john" child := "mary" query := fmt.Sprintf("parent(%s, %s).", parent, child) // 执行查询 solutions, err := m.Query(query) if err != nil { log.Fatal(err) } // 遍历结果 for solutions.Next() { fmt.Println("找到匹配结果!") } if err := solutions.Err(); err != nil { log.Fatal(err) } }
复合项示例(安全推荐)
用复合项构造查询是更结构化的方案,能彻底避免参数含特殊字符、空格时触发的语法错误,同时防止注入风险:
package main import ( "fmt" "log" "github.com/ichiban/prolog" "github.com/ichiban/prolog/engine" ) func main() { m := prolog.NewMachine() // 添加事实 err := m.Exec(`parent(john, mary).`) if err != nil { log.Fatal(err) } // 用engine.Atom包装参数 parent := engine.NewAtom("john") child := engine.NewAtom("mary") // 构造复合项查询 query := engine.NewCompound("parent", parent, child) // 执行查询 solutions, err := m.Query(query) if err != nil { log.Fatal(err) } for solutions.Next() { fmt.Println("找到匹配结果!") } if err := solutions.Err(); err != nil { log.Fatal(err) } }
我之前试过用动态字符串插值构建查询,本以为能正常返回结果,但遇到参数带特殊字符或空格时就会报错。后来才发现,用复合项才是更安全可靠的传参方式,能完全规避这类格式问题和注入风险。
内容的提问来源于stack exchange,提问作者William
相关产品推荐
相关产品推荐

