尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
从理论到实践:深入理解Norm的核心组件与实现原理
从理论到实践深入理解Norm的核心组件与实现原理【免费下载链接】normData specification and generation项目地址: https://gitcode.com/gh_mirrors/no/normNorm是一个用于指定数据结构的系统可用于数据验证和生成。它不提供特定的谓词集而是允许重用现有的任何验证逻辑为开发者提供了灵活且强大的数据规范解决方案。核心功能概览验证与生成的双重能力 ✨Norm的核心价值在于将数据规范与验证、生成能力无缝结合。通过统一的规范定义开发者可以同时实现数据验证和测试数据生成极大提升开发效率。数据验证确保输入符合预期Norm通过conform操作验证数据是否符合规范提供了conform/2和conform!/2两个主要函数。前者返回包含验证结果或错误信息的元组后者在验证失败时直接抛出异常。# 基础验证示例 import Norm # 成功验证 conform!(123, spec(is_integer() and (1 0))) # 返回 123 # 失败验证 conform!(-50, spec(is_integer() and (1 0))) # 抛出MismatchError验证功能的实现位于lib/norm.ex中主要通过Conformer.conform/2函数处理核心逻辑。数据生成从规范自动创建测试数据除了验证Norm还能基于规范自动生成符合要求的数据这对于属性测试、开发环境搭建和数据库种子数据创建非常有用。生成功能依赖StreamData库可通过gen/1函数触发。# 数据生成示例 user_schema schema(%{ name: spec(is_binary()), age: spec(is_integer() and (1 0)) }) # 生成3个符合规范的用户数据 generated_users user_schema | gen() | Enum.take(3)生成功能的核心实现位于lib/norm/generator.ex通过Generatable.gen/1函数处理规范到生成器的转换。核心组件解析构建数据规范的基石 Spec基础规范构建块spec/1是创建基本验证规则的宏支持任意谓词函数和逻辑组合是构建复杂规范的基础。# 基础spec定义 spec(is_binary()) # 验证二进制字符串 spec(is_integer() and (1 0)) # 验证正整数 spec(is_atom() or is_binary()) # 验证原子或二进制Spec的实现位于lib/norm/core/spec.ex通过Spec.build/1宏处理谓词的解析和组合。Schema映射与结构体规范schema/1用于定义映射和结构体的规范支持嵌套结构具有开放性特点——未指定的键会被保留所有键默认都是可选的。# 复杂嵌套schema示例 user_schema schema(%{ user: schema(%{ name: spec(is_binary()), age: spec(is_integer() and (1 0)) }) })Schema的实现位于lib/norm/core/schema.ex通过Schema.build/1函数处理映射结构的规范定义。Selection处理键的必填性虽然Schema默认所有键都是可选的但可以通过selection/2来指定必须存在的键提供了灵活的必填项控制。# 选择必填字段 just_age selection(user_schema, [user: [:age]]) conform!(%{user: %{name: chris}}, just_age) # 会失败因为age是必填的Selection的实现位于lib/norm/core/selection.ex通过Selection.new/2函数创建包含必填规则的选择器。Collection集合类型规范coll_of/2用于定义集合类型的规范支持列表、映射集等多种集合类型并可指定元素规范、长度限制等选项。# 集合规范示例 coll_of(spec(is_integer()), min_count: 1, max_count: 5) # 1-5个整数的集合 coll_of(spec(is_atom), into: MapSet.new()) # 转换为MapSetCollection的实现位于lib/norm/core/collection.ex通过Collection.new/2函数处理集合规范的定义。Alt与OneOf处理可选规范alt/1和one_of/1提供了处理多种可能规范的能力前者返回带标签的结果后者直接返回匹配的值。# 替代规范示例 event_spec alt(create: create_event_schema, update: update_event_schema) conform!(%{type: :create}, event_spec) # 返回 {:create, %{type: :create}} # 任意一个规范示例 one_of([spec(is_binary()), :alice]) # 匹配二进制或:alice原子Alt的实现位于lib/norm/core/alt.exOneOf则位于lib/norm/core/any_of.ex。高级特性函数契约与自定义生成器 函数契约确保函数输入输出符合规范Norm提供了contract注解用于定义函数的输入输出规范自动验证函数调用的参数和返回值。defmodule Colors do use Norm def rgb(), do: spec(is_integer() and (1 in 0..255)) def hex(), do: spec(is_binary() and String.starts_with?(1, #)) contract rgb_to_hex(r :: rgb(), g :: rgb(), b :: rgb()) :: hex() def rgb_to_hex(r, g, b) do # 实现转换逻辑 end end契约功能的实现位于lib/norm/contract.ex通过宏在编译时注入验证代码。自定义生成器引导数据生成过程当自动生成无法满足需求时可以使用with_gen/2自定义生成器精确控制生成数据的范围和分布。# 自定义生成器示例 age_spec spec(is_integer() and (1 0)) reasonable_ages with_gen(age_spec, StreamData.integer(0..105)) # 限制年龄在0-105之间生成器相关代码位于lib/norm/generator.ex通过Generator.new/2函数包装自定义生成逻辑。快速开始安装与基础使用指南 安装步骤将Norm添加到mix.exs的依赖列表中def deps do [ {:stream_data, ~ 0.4}, # 数据生成依赖 {:norm, ~ 0.13} # Norm主依赖 ] end基本使用流程定义规范使用spec/1、schema/1等函数创建数据规范验证数据使用conform/2或conform!/2验证输入数据生成数据使用gen/1从规范生成测试数据# 完整使用示例 import Norm # 1. 定义用户规范 user_schema schema(%{ name: spec(is_binary()), age: spec(is_integer() and (1 0)) }) # 2. 验证数据 valid_user %{name: Alice, age: 30} conform!(valid_user, user_schema) # 成功返回用户数据 # 3. 生成测试数据 test_users user_schema | gen() | Enum.take(5) # 生成5个测试用户实际应用场景与最佳实践 适用场景API请求验证确保传入的请求参数符合预期结构配置文件验证验证应用配置的完整性和正确性测试数据生成为单元测试和集成测试自动生成符合规范的测试数据函数契约确保函数调用和返回值符合预设规范提高代码可靠性最佳实践规范复用将通用规范提取为函数在多个地方复用渐进式验证从基础规范开始逐步添加复杂规则合理使用生成器结合自动生成和自定义生成器平衡测试覆盖率和性能明确错误处理使用conform/2获取详细错误信息便于调试总结Norm带来的数据规范新范式Norm通过统一的数据规范定义将验证和生成能力结合为Elixir开发者提供了处理数据结构的强大工具。其核心组件设计灵活既支持简单的类型检查也能应对复杂的嵌套结构验证。无论是构建API、处理配置还是编写测试Norm都能显著提升代码质量和开发效率。通过本文介绍的核心组件和使用方法你已经具备了在项目中应用Norm的基础知识。如需深入了解可查阅项目源代码和测试用例特别是test/norm/目录下的各类测试它们提供了丰富的使用示例和最佳实践参考。【免费下载链接】normData specification and generation项目地址: https://gitcode.com/gh_mirrors/no/norm创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED

相关推荐

5秒极速转换!m4s-converter:你的B站缓存视频永久保存方案

5秒极速转换!m4s-converter:你的B站缓存视频永久保存方案

5秒极速转换!m4s-converter:你的B站缓存视频永久保存方案 【免费下载链接】m4s-converter 一个跨平台小工具,将bilibili缓存的m4s格式音视频文件合并成mp4 项目地址: https://gitcode.com/gh_mirrors/m4/m4s-converter 你是否遇到过这…

📅 2026/11/15 18:33:30
亚马逊ERP哪个最好用?从功能、稳定性、价格三维度分析

亚马逊ERP哪个最好用?从功能、稳定性、价格三维度分析

一、选对亚马逊ERP,核心看“三维度”,避开选型内耗亚马逊卖家选ERP工具,易陷入“功能冗余”“价格虚高”“频繁卡顿”误区,盲目跟风选择,导致运营效率未提升、成本反而增加。那么,该怎么判断亚马逊ERP好不好…

📅 2026/9/28 8:37:51
metrics-spring扩展开发:自定义Reporter与SPI实现

metrics-spring扩展开发:自定义Reporter与SPI实现

metrics-spring扩展开发:自定义Reporter与SPI实现 【免费下载链接】metrics-spring Spring integration for Metrics 项目地址: https://gitcode.com/gh_mirrors/me/metrics-spring metrics-spring是Spring框架与Metrics集成的核心扩展,它允许开发…

📅 2026/10/6 17:46:08
MORE NEWS

更多资讯

📰

安监局电工证西安考点实操考试考什么 2025年最新官方报名入口全解析

安监局电工证西安考点实操考试考什么 2025年最新官方报名入口全解析 你是不是正在为找工作发愁?现在各行各业对 特种作业操作证 的要求越来越高,特别是像 电工证 这种基础又关键的证件, 急需特种作业证才能上岗找工作…

📰

佳木斯考电工证在哪里 良心建议帮你避开这些坑

佳木斯考电工证在哪里 良心建议帮你避开这些坑 之前考的证在外省能不能转过来?这个问题我听得太多了,尤其是从外地过来的朋友,最怕的就是证不能异地转过来,白白浪费时间和钱。今天就从 佳木斯考电工证在哪里 这个角度,结合我的亲身经历,给你一个…

📰

工地太忙根本没时间复习考试?低压电工证正规途径怎么报名全攻略

工地太忙根本没时间复习考试?低压电工证正规途径怎么报名全攻略 工地上的日子总是紧凑又辛苦,每天忙得连轴转,连喘口气的时间都没有。尤其是像低压电工这样的特种作业人员,不仅要在现场处理各种电气设备,还得时刻注意安全规范。但你知道吗?…

📰

江苏省+电工证+查询与呼市考电工证多少钱的区别

江苏省电工证查询千万别踩坑,工地太忙根本没时间复习考试 工地太忙根本没时间复习考试,这是很多电工从业者的心声。你可能正在为江苏省电工证的查询和办理发愁,或者担心自己持有的电工证是否有效、是否需要年审。别急,这篇文章将为你一一解答,…

📰

特种电工证机电怎么考?良心建议教你避开报名陷阱

特种电工证机电怎么考?良心建议教你避开报名陷阱 你是不是也在为特种电工证机电的报名发愁?不知道去哪报名怕被中介坑?别急,听我这个干了10年应急管理行业的老手给你说说门道。今天这波良心建议,绝对不是套路,是咱同行之间的硬核干货。…

📰

湖北省特种工考试时间最新出炉!外省证能转吗?郑州报考避坑指南

湖北省特种工考试时间最新出炉!外省证能转吗?郑州报考避坑指南 之前考的证在外省能不能转过来?这个问题我遇到过不下十次,每次都有人一脸迷茫地问我:“我在郑州考的特种作业证,现在回湖北工作,能用吗?”说实话,这个问题不是小问题,特别是像你这种在…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬