- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在 go 中创建了一个自定义 Set
数据类型,我用它来定义一对多关系。例如在我的架构中,我有以下结构定义
type Doctor struct {
firstName string
lastName string
capabilities commons.Set
}
这里 capabilities
是一组字符串,具有以下值 chat, audio, video
,通过此设置,我试图将上述结构保存到 MySQL
使用 GORM
库,但是当我这样做时出现以下错误
panic: invalid sql type Set (interface) for mysql
goroutine 6 [running]:
catalog/vendor/github.com/jinzhu/gorm.(*mysql).DataTypeOf(0xc00027e8a0, 0xc00024d680, 0x8, 0x8)
/home/kumard/go/src/catalog/vendor/github.com/jinzhu/gorm/dialect_mysql.go:123 +0xce9
catalog/vendor/github.com/jinzhu/gorm.(*Scope).createTable(0xc000169400, 0xc14e60)
我知道我必须实现某些方法才能实现这一点,但我无法弄清楚要在此处实现哪个方法/回调。
ThreadUnsafeSet 定义:
type threadUnsafeSet map[interface{}]struct{}
type OrderedPair struct {
First interface{}
Second interface{}
}
func newThreadUnsafeSet() threadUnsafeSet {
return make(threadUnsafeSet)
}
func (pair *OrderedPair) Equal(other OrderedPair) bool {
return pair.First == other.First && pair.Second == other.Second
}
func (set *threadUnsafeSet) Add(i interface{}) bool {
_, found := (*set)[i]
if found {
return false
}
(*set)[i] = struct{}{}
return true
}
func (set *threadUnsafeSet) Contains(i ...interface{}) bool {
for _, val := range i {
if _, ok := (*set)[val]; !ok {
return false
}
}
return true
}
func (set *threadUnsafeSet) Cardinality() int {
return len(*set)
}
func (set *threadUnsafeSet) Equal(other Set) bool {
_ = other.(*threadUnsafeSet)
if set.Cardinality() != other.Cardinality() {
return false
}
for elem := range *set {
if !other.Contains(elem){
return false
}
}
return true
}
func (set *threadUnsafeSet) IsSubSet(other Set) bool {
_ = other.(*threadUnsafeSet)
if set.Cardinality() > other.Cardinality() {
return false
}
for elem := range *set {
if !other.Contains(elem) {
return false
}
}
return true
}
func (set *threadUnsafeSet) IsProperSubSet(other Set) bool {
return set.IsSubSet(other) && !set.Equal(other)
}
func (set *threadUnsafeSet) IsSuperSet(other Set) bool {
return other.IsSubSet(set)
}
func (set *threadUnsafeSet) IsProperSuperSet(other Set) bool {
return set.IsSuperSet(other) && !set.Equal(other)
}
func (set *threadUnsafeSet) Union(other Set) Set {
o := other.(*threadUnsafeSet)
result := newThreadUnsafeSet()
for elem := range *set {
result.Add(elem)
}
for elem := range *o {
result.Add(elem)
}
return &result
}
func (set *threadUnsafeSet) Intersect(other Set) Set {
o := other.(*threadUnsafeSet)
intersection := newThreadUnsafeSet()
if set.Cardinality() < other.Cardinality() {
for elem := range *set {
if other.Contains(elem) {
intersection.Add(elem)
}
}
} else {
for elem := range *o {
if set.Contains(elem) {
intersection.Add(elem)
}
}
}
return &intersection
}
func (set *threadUnsafeSet) Difference(other Set) Set {
_ = other.(*threadUnsafeSet)
difference := newThreadUnsafeSet()
for elem := range *set {
if !other.Contains(elem) {
difference.Add(elem)
}
}
return &difference
}
func (set *threadUnsafeSet) SymmetricDifference(other Set) Set {
_ = other.(*threadUnsafeSet)
aDiff := set.Difference(other)
bDiff := other.Difference(set)
return aDiff.Difference(bDiff)
}
func (set *threadUnsafeSet) Clear(){
*set = newThreadUnsafeSet()
}
func (set *threadUnsafeSet) Remove(i interface{}) {
delete(*set, i)
}
func (set *threadUnsafeSet) Each(cb func(interface{}) bool) {
for elem := range *set {
if cb(elem) {
break
}
}
}
func (set *threadUnsafeSet) Iter() <-chan interface{} {
ch := make(chan interface{})
go func() {
for elem := range *set {
ch <- elem
}
close(ch)
}()
return ch
}
func (set *threadUnsafeSet) Iterator() *commons.Iterator {
iterator, ch, stopCh := commons.NewIterator()
go func (){
L:
for elem := range *set {
select {
case <-stopCh: {
break L
}
case ch <- elem:
}
close(ch)
}
}()
return iterator
}
func (set *threadUnsafeSet) Clone() Set {
clonedSet := newThreadUnsafeSet()
for elem := range *set {
clonedSet.Add(elem)
}
return &clonedSet
}
func (set *threadUnsafeSet) String() string {
items := make([]string, 0, len(*set))
for elem := range *set {
items = append(items, fmt.Sprintf("%v", elem))
}
return fmt.Sprintf("Set{%s}", strings.Join(items, ","))
}
func (pair OrderedPair) String() string {
return fmt.Sprintf("(%v, %v)", pair.First, pair.Second)
}
func (set *threadUnsafeSet) Pop() interface{} {
for item := range *set {
delete (*set, item)
return item
}
return nil
}
func (set *threadUnsafeSet) PowerSet() Set {
powSet := NewThreadUnsafeSet()
nullSet := newThreadUnsafeSet()
powSet.Add(&nullSet)
for _, v := range i {
switch t := v.(type) {
case []interface{}, map[string]interface{}:
continue
default:
set.Add(t)
}
}
return nil
}
func (set *threadUnsafeSet) FindAny() fi.Optional {
for elem := range *set {
return fi.MakeNullable(elem)
}
return fi.MakeNullable(nil)
}
func (set *threadUnsafeSet) FindFirst(predicate func(interface{}) bool) fi.Optional {
for elem := range *set {
if predicate(elem) {
return fi.MakeNullable(elem)
}
}
return fi.MakeNullable(nil)
}
func (set *threadUnsafeSet) RemoveAll(elementsToRemove ... interface{}) {
for _, elem := range elementsToRemove {
if set.Contains(elem) {
set.Remove(elem)
}
}
}
for es := range *set {
u := newThreadUnsafeSet()
j := powSet.Iter()
for err := range j {
p := newThreadUnsafeSet()
if reflect.TypeOf(err).Name() == "" {
k := err.(*threadUnsafeSet)
for ek := range *(k){
p.Add(ek)
}
}else {
p.Add(err)
}
p.Add(es)
u.Add(&p)
}
powSet = powSet.Union(&u)
}
return powSet
}
func (set *threadUnsafeSet) CartesianProduct(other Set) Set {
o := other.(*threadUnsafeSet)
cartProduct := NewThreadUnsafeSet()
for i := range *set {
for j := range *o {
elem := OrderedPair{First: i, Second: j}
cartProduct.Add(elem)
}
}
return cartProduct
}
func (set *threadUnsafeSet) ToSlice() []interface{}{
keys := make([]interface{}, 0, set.Cardinality())
for elem := range *set {
keys = append(keys, elem)
}
return keys
}
func (set *threadUnsafeSet) MarshalJSON() ([]byte, error) {
items := make([]string, 0, set.Cardinality())
for elem := range *set {
b, err := json.Marshal(elem)
if err != nil {
return nil, err
}
items = append(items, string(b))
}
return []byte(fmt.Sprintf("[%s]", strings.Join(items, ","))), nil
}
func (set *threadUnsafeSet) UnMarshalJSON(b []byte) error {
var i []interface{}
d := json.NewDecoder(bytes.NewReader(b))
d.UseNumber()
err := d.Decode(&i)
if err != nil {
return err
}
设置接口(interface)定义
type Set interface {
Add(i interface{}) bool
Cardinality() int
Clear()
Clone() Set
Contains(i ...interface{}) bool
Difference(other Set) Set
Equal(other Set) bool
Intersect(other Set) Set
IsProperSubSet(other Set) bool
IsSubSet(other Set) bool
IsSuperSet(other Set) bool
Each(func(interface{}) bool)
Iter() <-chan interface{}
Iterator() *commons.Iterator
Remove(i interface{})
String() string
SymmetricDifference(other Set) Set
Union(other Set) Set
Pop() interface{}
PowerSet() Set
CartesianProduct(other Set) Set
ToSlice() []interface{}
FindAny() fi.Optional
FindFirst(predicate func(interface{}) bool) fi.Optional
RemoveAll(...interface{})
}
// NewSet creates and returns a reference to an empty set. Operations
// on the resulting set are thread-safe.
func NewSet(s ...interface{}) Set {
set := newThreadSafeSet()
for _, item := range s {
set.Add(item)
}
return &set
}
// NewSetWith creates and returns a new set with the given elements.
// Operations on the resulting set are thread-safe.
func NewSetWith(elts ...interface{}) Set {
return NewSetFromSlice(elts)
}
// NewSetFromSlice creates and returns a reference to a set from an
// existing slice. Operations on the resulting set are thread-safe.
func NewSetFromSlice(s []interface{}) Set {
a := NewSet(s...)
return a
}
// NewThreadUnsafeSet creates and returns a reference to an empty set.
// Operations on the resulting set are not thread-safe.
func NewThreadUnsafeSet() Set {
set := newThreadUnsafeSet()
return &set
}
// NewThreadUnsafeSetFromSlice creates and returns a reference to a
// set from an existing slice. Operations on the resulting set are
// not thread-safe.
func NewThreadUnsafeSetFromSlice(s []interface{}) Set {
a := NewThreadUnsafeSet()
for _, item := range s {
a.Add(item)
}
return a
}
最佳答案
你需要实现Scanner &司机Valuer自定义类型的接口(interface)那么数据库驱动程序就可以知道如何将数据存储在数据库中以及如何从数据库中获取数据。
func (data *CustomType) Value() (driver.Value, error) {
...
}
func (data *CustomType) Scan(value interface{}) error {
...
}
示例:假设 UserAccess 是 map[interface{}]struct{}
类型。
type UserAccess map[interface{}]struct{}
func (data *UserAccess) Value() (driver.Value, error) {
return data.ConvertJSONToString(), nil
}
func (data *UserAccess) Scan(value interface{}) error {
*data = data.ConvertStringToJson(valueString)
}
这里 ConvertStringToJson
和 ConvertJSONToString
用于将自定义数据类型值转换为数据库兼容类型,如 json-string。
关于go - 使用 GORM golang 持久化自定义集数据类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61073209/
我正在尝试运行这段代码,用随机数替换字符串中的一个字符: //Get the position between 0 and the length of the string-1 to insert
我有一个包含 3 个位置的数组,假设它的所有位置都是数字 5。 [5 5 5] 我怎样才能以保持 555 的方式将它传递给 var?就像这样。 n:= 555 最佳答案 与使用任何其他语言的方式相同:
我使用 go dep 工具版本 v0.4.1,现在当我运行 dep init 时它会按预期创建 2 个文件,当我打开 gopkg.lock 我发现例如以下内容 [[projects]] name
我正在制作学习联系申请。我有一个 NewContact()。 // Contact - defines the fields of an entire Contact type Contact str
我一直在尝试使用该模块: https://godoc.org/github.com/hirochachacha/go-smb2#RemoteFile.ReadAt 为了在 Windows 机器上对我的
我需要在 golang 中编译 golang 中的程序。有没有不使用 exec.Command("go","build") 的原生形式? 最佳答案 不幸的是,我认为使用 exec.Command 是利
编写输出有效 go 代码的 go 应用程序可能最好使用内置的“go”包及其一些子包(“go/ast”、“go/token”、“go/printer”、等)。 要创建字符串文字表达式,您需要创建一个 a
我正在尝试使用 Golang 和 gin 为我的 api 和前端编写代理。如果请求转到除“/api”之外的任何内容,我想代理到 svelte 服务器。如果出现“/api/something”,我想在
我偶然发现了这个博客:using go as a scripting language并尝试创建一个可用于运行 golang 脚本的自定义图像,即 FROM golang:1.15 RUN go ge
我刚开始接触golang,我需要从json字符串中获取数据。 {"data" : ["2016-06-21","2016-06-22","2016-06-25"], "sid" : "ab", "di
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 3 年前。 Improve
我是 goland 的新手,试图在我的第一个项目中使用它。我注意到在 goland 中它没有显示通过容器引入的相同 golang SDK。 这是我的 Dockerfile: FROM golang:1
我正在试用 golang-neo4j-bolt-driver 包 github.com/johnnadratowski/golang-neo4j-bolt-driver 我已经导入了包并正在使用创建新
如果我安装了Go发行版软件包,则会在/usr/lib/golang/pkg中看到很多文件,在/usr/lib/golang/src中看到非常相似的文件集。这两组之间有什么关系? pkg是从src中的源
我发现 golang 上下文对于在客户端-服务器请求范围内取消服务器的处理很有用。 我可以使用 http.Request.WithContext 方法发出带有上下文的 http 请求,但是如果客户端不
我正在尝试将一个 golang 数组(还有 slice、struct 等)放置到 HTML 中,这样当从 golang gin web 框架返回 HTML 时,我可以在 HTML 元素内容中使用数组元
目前正在使用这个 ffmpeg 命令编辑视频 ffmpeg -i "video1.ts" -c:v libx264 -crf 20 -c:a aac -strict -2 "video1-fix.ts
我需要从 play.golang.org 链接读取 golang 代码并保存到 .go 文件。我想知道 play.golang.org 是否有任何公共(public) API 支持。我用谷歌搜索但没有
我第一次使用 IntelliJ 的最新 (2014-01-03) Golang 插件。 通常,我的终端工作流程是 go build && ./executable -args=1 所以我试图创建一个启
这个问题只是在构建之间随机出现,现在甚至我们的生产 repo,几个月都没有改变,在构建时也会出现这个问题。我已经坚持了一段时间。它不会发生在我们的本地机器上,只有在使用 dockerfile 时才会发
我是一名优秀的程序员,十分优秀!