golang 断言:一个蛋疼的处理场景

本贴最后更新于 1093 天前,其中的信息可能已经时过境迁

这一切都来源于一个蛋疼的需求场景处理:

因为历史原因,一个需要用到的 JSON 数据被整个缓存进 Redis 的一个 key 中,大概如下:

127.0.0.1:6379> get dt
"{\"address\":[{\"duration\":90,\"format\":\"mp4\",\"url\":\"xxx.mp4\",\"ext\":\"{\\\"key\\\":\\\"val\\\"}\"},{\"duration\":90,\"format\":\"mp4\",\"url\":\"xxx.mp4\",\"ext\":\"{\\\"key\\\":\\\"val\\\"}\"}],\"value\":\"web\"}"
127.0.0.1:6379>

这里还是做了脱敏处理,实际的情形 JSON 的层级更深...
格式化显示的 JSON 结构大概是这样:

{
    "address": [
        {
            "duration": 90,
            "format": "mp4",
            "url": "xxx.mp4",
            "ext": "{\"key\":\"val\"}"
        },
        {
            "duration": 90,
            "format": "mp4",
            "url": "xxx.mp4",
            "ext": "{\"key\":\"val\"}"
        }
    ],
    "value": "web"
}

现在要做的是: address 里的每个元素的 url 字段需要更新。

现在知道的是:address 的值 是一个数组,数组的每个元素是一个 map[string]interface{} 类型,map 里的元素除了 "url": "xxx.mp4" , 其他的数量不确定

实现代码大概如下(方便展示,省略了 Redis 读写的步骤):

	detailByte := []byte(`{"address":[{"duration":90,"format":"mp4","url":"xxx.mp4","ext":"{\"key\":\"val\"}"},{"duration":90,"format":"mp4","url":"xxx.mp4","ext":"{\"key\":\"val\"}"}],"value":"web"}`)
	detail := make(map[string]interface{}, 0)
	json.Unmarshal(detailByte, &detail)
	formatJson, _ := json.MarshalIndent(detail, "", "    ")
	fmt.Println("before: ", string(formatJson))
	if address, ok := detail["address"]; ok {
		if item, ok2 := address.([]interface{}); ok2 {
			for index, value := range item {
				if vMap, ok3 := value.(map[string]interface{}); ok3 {
					if _, ok4 := vMap["url"]; ok4 {
						vMap["url"] = "wtf.mp4"
					}
					item[index] = vMap
				}
			}
			detail["address"] = item
		}
	}
	formatJson, _ = json.MarshalIndent(detail, "", "    ")
	fmt.Println("after: ", string(formatJson))

运行结果:

before:  {
    "address": [
        {
            "duration": 90,
            "ext": "{\"key\":\"val\"}",
            "format": "mp4",
            "url": "xxx.mp4"
        },
        {
            "duration": 90,
            "ext": "{\"key\":\"val\"}",
            "format": "mp4",
            "url": "xxx.mp4"
        }
    ],
    "value": "web"
}
after:  {
    "address": [
        {
            "duration": 90,
            "ext": "{\"key\":\"val\"}",
            "format": "mp4",
            "url": "wtf.mp4"
        },
        {
            "duration": 90,
            "ext": "{\"key\":\"val\"}",
            "format": "mp4",
            "url": "wtf.mp4"
        }
    ],
    "value": "web"
}

怎么说呢,实现了感觉又没有真正实现...

哎,蛋疼。

  • golang

    Go 语言是 Google 推出的一种全新的编程语言,可以在不损失应用程序性能的情况下降低代码的复杂性。谷歌首席软件工程师罗布派克(Rob Pike)说:我们之所以开发 Go,是因为过去 10 多年间软件开发的难度令人沮丧。Go 是谷歌 2009 发布的第二款编程语言。

    497 引用 • 1387 回帖 • 292 关注
  • 类型断言
    1 引用 • 2 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • yliu7949 1

    没接触过 Redis,但如果 json 数据可以转化为 string 类型的话,那么可以试试 "github.com/tidwall/sjson" 这个包,核心语句只有一行 sjson.Set(json, "address.#.url", "wtf.mp4")

    代码:

    package main
    
    import "github.com/tidwall/sjson"
    
    const json = `{
        "address": [
            {
                "duration": 90,
                "ext": "{\"key\":\"val\"}",
                "format": "mp4",
                "url": "xxx.mp4"
            },
            {
                "duration": 90,
                "ext": "{\"key\":\"val\"}",
                "format": "mp4",
                "url": "xxx.mp4"
            }
        ],
        "value": "web"
    }`
    
    func main() {
    	value, _ := sjson.Set(json, "address.#.url", "wtf.mp4")
    	println(value)
    }
    

    输出:

    {
        "address": [
            {
                "duration": 90,
                "ext": "{\"key\":\"val\"}",
                "format": "mp4",
                "url": "wtf.mp4"
            },
            {
                "duration": 90,
                "ext": "{\"key\":\"val\"}",
                "format": "mp4",
                "url": "wtf.mp4"
            }
        ],
        "value": "web"
    }
    
    1 回复
  • xuanskyer
    作者

    妙啊!

    1 操作
    xuanskyer 在 2021-12-06 16:22:38 更新了该回帖

推荐标签 标签

  • RESTful

    一种软件架构设计风格而不是标准,提供了一组设计原则和约束条件,主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

    30 引用 • 114 回帖 • 2 关注
  • FlowUs

    FlowUs.息流 个人及团队的新一代生产力工具。

    让复杂的信息管理更轻松、自由、充满创意。

    1 引用 • 2 关注
  • Notion

    Notion - The all-in-one workspace for your notes, tasks, wikis, and databases.

    6 引用 • 38 回帖
  • 单点登录

    单点登录(Single Sign On)是目前比较流行的企业业务整合的解决方案之一。SSO 的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。

    9 引用 • 25 回帖 • 5 关注
  • 酷鸟浏览器

    安全 · 稳定 · 快速
    为跨境从业人员提供专业的跨境浏览器

    3 引用 • 59 回帖 • 28 关注
  • 数据库

    据说 99% 的性能瓶颈都在数据库。

    343 引用 • 719 回帖
  • FFmpeg

    FFmpeg 是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。

    23 引用 • 32 回帖 • 2 关注
  • 创造

    你创造的作品可能会帮助到很多人,如果是开源项目的话就更赞了!

    179 引用 • 996 回帖
  • GAE

    Google App Engine(GAE)是 Google 管理的数据中心中用于 WEB 应用程序的开发和托管的平台。2008 年 4 月 发布第一个测试版本。目前支持 Python、Java 和 Go 开发部署。全球已有数十万的开发者在其上开发了众多的应用。

    14 引用 • 42 回帖 • 766 关注
  • DevOps

    DevOps(Development 和 Operations 的组合词)是一组过程、方法与系统的统称,用于促进开发(应用程序/软件工程)、技术运营和质量保障(QA)部门之间的沟通、协作与整合。

    48 引用 • 25 回帖 • 3 关注
  • 前端

    前端技术一般分为前端设计和前端开发,前端设计可以理解为网站的视觉设计,前端开发则是网站的前台代码实现,包括 HTML、CSS 以及 JavaScript 等。

    247 引用 • 1348 回帖
  • CAP

    CAP 指的是在一个分布式系统中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可兼得。

    11 引用 • 5 回帖 • 609 关注
  • 又拍云

    又拍云是国内领先的 CDN 服务提供商,国家工信部认证通过的“可信云”,乌云众测平台认证的“安全云”,为移动时代的创业者提供新一代的 CDN 加速服务。

    21 引用 • 37 回帖 • 546 关注
  • Sphinx

    Sphinx 是一个基于 SQL 的全文检索引擎,可以结合 MySQL、PostgreSQL 做全文搜索,它可以提供比数据库本身更专业的搜索功能,使得应用程序更容易实现专业化的全文检索。

    1 引用 • 217 关注
  • VirtualBox

    VirtualBox 是一款开源虚拟机软件,最早由德国 Innotek 公司开发,由 Sun Microsystems 公司出品的软件,使用 Qt 编写,在 Sun 被 Oracle 收购后正式更名成 Oracle VM VirtualBox。

    10 引用 • 2 回帖 • 2 关注
  • SVN

    SVN 是 Subversion 的简称,是一个开放源代码的版本控制系统,相较于 RCS、CVS,它采用了分支管理系统,它的设计目标就是取代 CVS。

    29 引用 • 98 回帖 • 685 关注
  • 招聘

    哪里都缺人,哪里都不缺人。

    190 引用 • 1057 回帖
  • Shell

    Shell 脚本与 Windows/Dos 下的批处理相似,也就是用各类命令预先放入到一个文件中,方便一次性执行的一个程序文件,主要是方便管理员进行设置或者管理用的。但是它比 Windows 下的批处理更强大,比用其他编程程序编辑的程序效率更高,因为它使用了 Linux/Unix 下的命令。

    123 引用 • 74 回帖
  • 游戏

    沉迷游戏伤身,强撸灰飞烟灭。

    177 引用 • 816 回帖 • 1 关注
  • 以太坊

    以太坊(Ethereum)并不是一个机构,而是一款能够在区块链上实现智能合约、开源的底层系统。以太坊是一个平台和一种编程语言 Solidity,使开发人员能够建立和发布下一代去中心化应用。 以太坊可以用来编程、分散、担保和交易任何事物:投票、域名、金融交易所、众筹、公司管理、合同和知识产权等等。

    34 引用 • 367 回帖
  • Kotlin

    Kotlin 是一种在 Java 虚拟机上运行的静态类型编程语言,由 JetBrains 设计开发并开源。Kotlin 可以编译成 Java 字节码,也可以编译成 JavaScript,方便在没有 JVM 的设备上运行。在 Google I/O 2017 中,Google 宣布 Kotlin 成为 Android 官方开发语言。

    19 引用 • 33 回帖 • 62 关注
  • webpack

    webpack 是一个用于前端开发的模块加载器和打包工具,它能把各种资源,例如 JS、CSS(less/sass)、图片等都作为模块来使用和处理。

    41 引用 • 130 回帖 • 259 关注
  • 旅游

    希望你我能在旅途中找到人生的下一站。

    90 引用 • 899 回帖
  • RYMCU

    RYMCU 致力于打造一个即严谨又活泼、专业又不失有趣,为数百万人服务的开源嵌入式知识学习交流平台。

    4 引用 • 6 回帖 • 54 关注
  • 大数据

    大数据(big data)是指无法在一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合,是需要新处理模式才能具有更强的决策力、洞察发现力和流程优化能力的海量、高增长率和多样化的信息资产。

    93 引用 • 113 回帖
  • RabbitMQ

    RabbitMQ 是一个开源的 AMQP 实现,服务器端用 Erlang 语言编写,支持多种语言客户端,如:Python、Ruby、.NET、Java、C、PHP、ActionScript 等。用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。

    49 引用 • 60 回帖 • 365 关注
  • Logseq

    Logseq 是一个隐私优先、开源的知识库工具。

    Logseq is a joyful, open-source outliner that works on top of local plain-text Markdown and Org-mode files. Use it to write, organize and share your thoughts, keep your to-do list, and build your own digital garden.

    6 引用 • 63 回帖 • 4 关注