在那种应用场景下使用?
1
MidGap 2021-09-14 17:14:28 +08:00
这个有啥问题吗 0.0
|
2
tyx1703 2021-09-14 17:16:16 +08:00 via iPhone 6
序列化 json 要导出才行
|
3
chaleaoch OP @MidGap 我觉得可能是 2 楼的原因.
你有没有考虑过一个私有的结构体, 里面的字段是私有的还是公有的, 其实是没有区别的?' 除非和 Json 中的反射发生关系, 也就是说 ValueOf 只能获取公有的字段.或者...有什么我不知道的特别的场景. |
5
tyx1703 2021-09-14 17:27:56 +08:00 via iPhone
@chaleaoch 过誉了,只是经验之谈。
正常来说是的,不过有 hack 的方法 https://stackoverflow.com/questions/11126793/json-and-dealing-with-unexported-fields |
6
chaleaoch OP |
7
iyear 2021-09-14 17:31:43 +08:00
可能是一个第三方包,人家只是想自己在包里调用,不想暴露出去
|
9
chaleaoch OP |
11
cyrivlclth 2021-09-14 19:28:15 +08:00
除了反射,还有场景是提供一个默认的全局变量。。。
如 var DefaultUserInfo = userInfo{...} 这个 DefaultUserInfo 是可以导出的。 userInfo 也可能是某个结构体的一个字段。 |
12
cyrivlclth 2021-09-14 19:29:38 +08:00 1
还有种就是不希望调用方直接使用 UserInfo{}这样的形式使用,而是使用提供的 New 方法去使用
|
13
yin1999 2021-09-14 19:36:00 +08:00 via Android
应该是为了序列化使用(包含了 JSON 的 tag ),而这个结构体本身是不导出的,所以正常使用,它里面的字段是不会被包的使用者直接修改的
|
14
ihipop 2021-09-14 20:07:11 +08:00 via Android 1
结构体私有不代表不能被外部使用,你可以通过一个 new 函数或者包公共变量把它 return 出去
|
15
chaleaoch OP @cyrivlclth 大佬 这种骚操作的意义是什么?
|
16
chaleaoch OP @cyrivlclth 骚操作是指 var DefaultUserInfo = userInfo{...}这个.
================================= userInfo 也可能是某个结构体的一个字段。 譬如叫结构体 AAA 好了, 那么其他包可以通过 AAA 访问 userInfo 吗? ================================= 还有种就是不希望调用方直接使用 UserInfo{}这样的形式使用,而是使用提供的 New 方法去使用 有道理. |
17
chaleaoch OP |
18
chaleaoch OP 接楼上, "那么调用这个工厂方法的变量如何定义" 没说清楚,
我是指, 调用这个工厂方法的赋值语句需要一个变量接受 New 出来的结构体, 这个变量如何定义. 只有一种可能就是接口.有这么用的么... |
19
cyrivlclth 2021-09-14 22:53:47 +08:00
@chaleaoch 变量定义直接 var 或者 := 就行呀,又不是老版本的 java 不支持 var
|
20
chaleaoch OP @cyrivlclth 我试了一下真的可以... 有点假
|
21
cyrivlclth 2021-09-14 23:11:35 +08:00
@chaleaoch =。=你说的那种骚操作我在公司项目中看到过,写这个的人美曰其名是隔离(因为那个 package 导入之后,你按.之后的提示不会有 userInfo,只会有一个 DefaultUserInfo ),但其实在我看来就是没啥大用,就只是本来那个只需要用一次,就定义匿名结构体,但是匿名结构体写法又太难受了,就整个私有但是有公有字段的结构体出来。
但大部分这种情形都是为了反射。 |
22
cyrivlclth 2021-09-14 23:13:09 +08:00
@chaleaoch 哦,对了,我们那个变量名叫 DefaultConfig,是从 toml 文件解析,所以还真得用公有字段
|
23
chaleaoch OP @cyrivlclth 谢谢 还剩一个问题 我本地试了一下. 大概明白了 大小写隔离的 是类似链接的功能 并不是内存级别的隔离. 只要我能看见你我就能用你, 而不是从内存检查你到底是否是可见的.
学到了学到了. 谢谢大佬指点. |
24
XTTX 2021-09-15 09:34:41 +08:00
上面的答案都不全。struct 里使用 custom type,同时需要自己写符合 marshal unmarshal function signature 的 method.
|
25
XTTX 2021-09-15 09:35:31 +08:00
============================================
|
26
XTTX 2021-09-15 09:45:54 +08:00 1
你要 unmarshal users.Permissions 就必须提供
func (u *users.Permissions) UnMarshalJSON() ([]byte, error) { } func (u *users.Permissions) MarshalJSON(data []byte) error { } 你在 marshal 整个 UserInfo 的时候,你提供的针对 users.Permissions 的 marshaller 会自动被调用。 ============================================================ 比如,很多时候 users.Permissions 是 null, 你不提供上述 method, 整个 marshal 过程会报错。 |
27
XTTX 2021-09-15 09:47:08 +08:00
=================================================
// NullString is an alias for sql.NullString data type type NullString struct { sql.NullString } // MarshalJSON for NullString func (ns *NullString) MarshalJSON() ([]byte, error) { if !ns.Valid { return []byte("null"), nil } return json.Marshal(ns.String) } // UnmarshalJSON for NullString func (ns *NullString) UnmarshalJSON(b []byte) error { err := json.Unmarshal(b, &ns.String) ns.Valid = (err == nil) return err } =================================================== type ArticleAction struct { ID int `db:"articleaction_id" json:"id"` Notes NullString `db:"notes,omitempty" json:"notes,omitempty"` } |