首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么Eunit坚持我的函数返回{ok,value},而不是呢?

EUnit是一种用于Erlang编程语言的单元测试框架。它要求被测试函数返回{ok, Value}的原因是为了实现测试结果的准确判断和数据提取。

  1. 准确判断:EUnit通过比较返回的结果与期望值来确定测试是否通过。使用{ok, Value}的形式,可以清楚地表示函数执行成功,并且提供了一个值供进一步验证。如果函数返回其他形式的结果,无法明确表达执行成功的状态,将会导致测试结果的不准确性。
  2. 数据提取:{ok, Value}的形式可以让我们轻松地从结果中提取需要的数据进行进一步处理或验证。比如,我们可以使用模式匹配来获取返回值中的具体数据,这在测试中非常方便。

举例来说,假设我们有一个函数add/2用于两个整数相加,期望返回它们的和。如果函数返回的结果是整数类型,那么在进行测试时,我们无法区分是否执行成功以及获取具体的计算结果。而使用{ok, Value}的形式,我们可以这样断言和提取结果:

代码语言:txt
复制
add_test() ->
    Result = add(2, 3),
    ?assertEqual({ok, 5}, Result),
    {ok, Sum} = Result,
    ?assertEqual(5, Sum).

上述代码中,?assertEqual/2用于断言结果是否与期望值相等,{ok, Sum} = Result则用于从结果中提取和值并进行进一步验证。

根据上述理由,EUnit鼓励使用{ok, Value}的形式,以确保测试结果的准确性和方便性。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

『Go 语言学习专栏』-- 第二期

对于初学者,或者说自学编程的人, 非常理解他们自学烦恼在哪里。 因为也是从自学一路过来。都会经历这些过程, 坚持下去就行, 相信我, 你幷不孤独....但为什么不同的人写代码、文章存在很大差异,有些人写好,有些人写不好。 这其实是代码组织或者文字组织。...这一点,其实之前不是太注意。最近不是在阅读《代码大全》嘛。 写一些代码片段可能不太能感受到这些原则能有什么样益处。一旦你项目越来越复杂时候,你别头疼。...但是建议使用显式声明 使用 原则: 变量声明,靠近使用处: 即你需要使用变量就在要使用地方声明变量,不是提前声明一大堆,或者远离使用变量地方,不利于阅读 多个变量声明放一起 var ( url...函数分为这麽几类: 匿名函数 结构体方法 普通函数 要写好函数注意下面几点: 函数名称: 见文知意 参数 返回值 匿名函数: 即没有名称函数, 字面意思, 一般用来处理简单函数 func main

40450
  • 如何优雅高效地节省内存?官方给出了 12 个经典用法

    花下猫语:有时候,预定计划被临时打乱。这时候怎么办?拒绝它并按照原计划进行,还是接受它并调整计划? 有时候,预期效果没有达到。这时候又该怎么办?...下次调整做法来迎合别人,还是坚持初心斗志昂然? 选择是一条中庸之道,想要兼顾,不偏不倚,不左不右,敢于求变,勇于守成。 ?...不打算笼统介绍它们所能实现功能,而是想分析这些功能背后实现代码,它们如何做到高效节省内存,Python内核贡献者们又是如何写出一手漂亮代码,这很有趣,不是吗?...与chain简单yield不同,此处稍微复杂一点,yield有点像return,所以 yield total那行直接就返回一个元素,也就是iterable第一个元素,因为任何时候这个函数返回第一个元素就是它第一个...又因为yield返回是一个generator对象,比如名字gen,所以next(gen)时,代码将会执行到 for element in it:这行,此时迭代器it 已经指到iterable第二个元素

    51610

    浅习一波JavaScript高级程序设计(第4版)p7-迭代器

    即: for 循环不适用遍历所有数据结构; ES5 发布了 forEach ,并没有做出任何改善,反而也是弊端多多: 不能使用 break 语句中断循环; 不能使用 return 语句返回到外层函数;...执行该函数 [Symbol.iterator](),会返回一个遍历器对象。只要数据结构拥有 Symbol.iterator属性,那么它就是 “可遍历” 。...咱就是说 ES6 为啥要搞一个迭代器,或者说迭代器优势在哪里?...迭代器是一种设计模式,为遍历不同数据结构 “集合” 提供统一接口;能遍历访问 “集合” 数据中项,不关心项数据结构。 OK,以上便是本篇分享。...觉得不错点个赞吧,您鼓励,动力,坚持原创质量好文~~ 欢迎评论留言 是掘金安东尼,输出暴露输入,技术洞见生活。再会吧~~

    43810

    函数式编程了解一下(上)

    为什么他重要 在理解什么是函数式编程开始,我们先了解下什么数学中,函数具有的特性 函数必须总是接受一个参数 函数必须总是返回一个值 函数应该依据接受到参数,不是外部环境运行 对于一个指定x,必须返回一个确定...等等,你这个forEach函数哪来嘛!对,也是自己写,但是不是我们通过编写这种抽象逻辑代码,让整体业务代码更加清晰明了了?...开发者是需要关心手头上问题就好了,只需要告诉编译器去干嘛不是怎么干了。是不是轻松了? 其实函数式编程主张就是以抽象方式创建函数。这些函数可以在代码其他部分被重用。...我们就可以说对于同样输出,总是返回同样结果,所以我们为什么不能够运用一个对象将我们每一次运算结果存起来?...抽象让我们专注于预定目标不是去关心底层系统概念。

    50230

    对于React Hook思考探索

    最喜欢函数组件,代码更加简洁,没有什么花里胡哨新概念,而且可以让避免跟this打交道。...import { useEffect } from 'react' useEffect(didUpdate) useContext接受一个Context对象,返回一个Context值。...我们可以发现,Hook更偏向于我们向React声明我们想要什么,这一点类似于我们界面描述方式,我们只说我们要什么,不是告诉框架该怎么做,代码也更加简洁,方便其他人理解跟后期维护,通过函数方式我们也可以在组件间共享逻辑...最终我们要把这个状态值跟设置方法以数组形式返回出去: return [ value, setState ] } 一个简单Hook就实现了,Hook其实就是简单js函数,用来执行一些有副作用操作...虽然有时候我们会觉得能在条件语句或者循环中这样使用Hook更好,但是React团队为什么这么设计?有木有更好方案

    1.3K10

    面试官问 async、await 函数原理是在问什么?

    它们有什么区别?...) + '"')); } }); } 看到这里,产生了一个疑问:Promise + then 也可以处理异步编程,为什么 co 源码里要把 Promise + generator 结合起来...next 函数 源码 next 函数接收一个 gen.next() 返回对象 ret 作为参数,形如{value: T, done: boolean},next 函数只有四行代码。...感想 对来说,学习一个新东西(generator)花费时间远远大于单纯阅读源码时间,因为需要了解它产生背景,语法,解决问题以及一些应用场景,这样在阅读源码时候才知道它为什么要这样写。...,如果不是这次活动,可能还要晚个大半年才接触到 generator,接触协程概念,了解到 async/await 实现原理,希望能够继续坚持下去~

    62830

    TypeScript 官方手册翻译计划【十二】:类

    关于 C# 为什么会认为这段代码是不合法,可以阅读这篇文章了解更多信息:为什么无法在一个派生类中去访问一个受保护成员?...在这个例子中,由于我们通过 obj 引用去调用函数,所以它 this 值是 obj,不是类实例。 这通常不是我们期望结果!...箭头函数 如果你函数在被调用时候经常会丢失 this 上下文,那么最好使用箭头函数属性,不是方法定义: class MyClass { name = 'MyClass'; getName...这种方法利弊权衡和上面使用箭头函数方法相反: JavaScript 调用方可能仍然会在没有意识情况下错误地调用类方法 只会给每个类定义分配一个函数不是给每个类实例分配一个函数 仍然可以通过...将 set 返回值类型推断为 this,不是 Box。

    2.6K10

    你不知道 TypeScript 泛型(万字长文,建议收藏)

    首先来思考一个问题:为什么要有泛型?这个原因实际上有很多,在这里选择大家普遍认同一个切入点来解释。如果你明白了这个点,其他点相对而言理解起来会比较轻松。还是通过一个例子来进行说明。...实际上知道传给你是 string,返回也一定是 string, string 上没有 toFixed 方法,因此需要报错才是想要。...我们脑洞一下,假如我们可以「像操作函数那样操作类型」,是不是有可能?比如我定义了一个函数 Partial,这个函数功能入参是一个类型,返回值是新类型,这个类型里属性全部变成可选。...因此这里就起了 T 不是 Type,更短了。这也算是一种约定俗称规范,大家一般习惯叫 T, U 等表示泛型形参。 ❞ 我们来看下完整泛型和函数有多像! ? (定义) ?...改成这样是 ok : type Lucifer = LeetCode; 泛型为什么使用尖括号 为什么泛型要用尖括号(),不是别的?

    2.3K30

    如何编写高质量 JS 函数(4) --函数式编程

    OK ,下面就先向大家展示一下,如何完全重构这段代码。...(3)注意有没有明显命令式编程 -- 声明式/抽象/封装 注意函数里面有没有大量 for 循环 为什么说这个,因为这个很好判断。...比如 name 是数字,age 返回不是数字。这样的话, if 中判断是能通过,但是实际结果并不是想要。 那该怎么办?问题不大,跟着一步步优化就 OK 了。...各种讨论,这里按照看法来解释一下,为什么会存在干掉 for 循环这一说。...计算就意味着消耗各种资源,做重复计算,就是在浪费各种资源。 纯洁性和缓存有什么关系?我们想一下可以知道,纯函数总是为给定输入返回相同输出,那既然如此,我们当然要想到可以缓存函数输出。

    2K41

    golang 闭包

    就让我们回顾这个古老又现代编程模型,看看究竟是什么魔力将这个概念在21世纪今天再次拉入我们视野 闭包是函数式编程语言中概念,没有研究过函数式语言的人可能很难理解闭包强大(就是其中一个,看见第一眼就是一脸懵逼...其中约束是指一个变量名字和其所代表对象之间联系。那么为什么要把引用环境与函数组合起来?这主要是因为在支持嵌套作用域语言中,有时不能简单直接地确定函数引用环境。...这样语言一般具有这样特性 函数是一等公民(First-class value),即函数可以作为另一个函数返回值或参数,还可以作为一个变量值。...那么是不是可以表示为一个结构体: type Closure struct { F func()() i *int } 事实上,Go在底层确实就是这样表示一个闭包。...其实这里adder函数返回就是闭包。 这个就是Go中闭包,一个函数和与其相关引用环境组合而成实体。一句关于闭包名言: 对象是附有行为数据,闭包是附有数据行为。

    1.8K31

    两数之和

    前言 秋招结束,面试了大大小小公司,最大问题在于算法上。所以打算坚持在leetcode打卡,看看到底能不能行,如果你想见证,那我来开车,你坐稳,一起走向更好远方。...ok外层循环从第一个数开始遍历,内层循环从第二个数遍历,如果这两个数和等于目标值,返回下标,问题来了,返回下标,所以需要先暂存起来才方便,而且返回类型也需要确定。...在这里,返回类型为vector,然后可以直接使用{i,j}方式来存储下标。好了,代码呈上!...从定义来说是根据关键码值(Key value)直接进行访问数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找速度。...确定返回值类型为vector 在c++中类似hash这种key,value容器有map,unorder_map等,我们选择unordered_map。

    36520

    10个实用但偏执Java编程技术

    这就是为什么我们要采用“防御性编程”,即一些偏执习惯原因。下面是个人认为10个最有用但偏执Java编程技术。...也许到时候他们改变了编码方式,对字符串并不区分大小写,也许更好方式是返回-2?谁知道。 4.避免意外赋值 是的。这种事情也许经常会发生。...话虽如此,不相信我自己是因为… ? …这就是为什么所有的变量和参数都是final原因。...9.总是在Switch语句Default中抛出异常 Switch语句……它们其中一个可笑语句不知道该对它敬畏还是哭泣,但无论如何,既然我们坚持用switch,那我们不妨将它用得完美,看下面的代码:...== 3时,将会出现无法找到提示,不会让人不知所谓。

    977130

    Go Context 详解之终极无惑

    父协程与子孙协程之间是关联在一起,他们需要共享请求相关信息,比如用户登录态,请求超时时间等。如何将这些协程联系在一起,context 应运而生。 话说回来,为什么要将这些协程关联在一起?...实现该接口类型有 *cancelCtx 和 *timerCtx。 为什么其中一个方法 cancel() 首字母是小写,未被导出, Done() 确是导出一定要实现?为何如此设计?...什么时候会传 true ?答案是调用 WithCancel() 方法时候,也就是新创建一个用于取消 context 结点时,返回 cancelFunc 函数会传入 true。...这种情况一般发生在一个 struct 匿名嵌套了 Context,就识别不出来了,因为parent.Value(&cancelCtxKey)返回是*struct,不是*cancelCtx。...注意是后台服务,不是所有的场景都需要使用 Context。 Go 官方建议我们把 Context 作为函数第一个参数,甚至连名字都准备好了。

    4.1K43

    Golang 语言中 map 有哪些陷阱?

    Golang 语言中 map 在查询元素时,实际上会有两个返回值,第一个返回值是 map value 值,第二个返回值是布尔类型,用于判定该 key 是否存在,因为 Golang 语言中 map...在查询指定 key value 值时,如果该 key 不存在,也不会报错,将会返回该 map value 相应类型零值。...这个隐藏陷阱可是让不少初学者痛苦万分,所以我们在查询 map 指定 key value 值时,最好是用两个变量接收返回值。..."] if ok { fmt.Println(name) } 04 并发操作 map 在 Golang 语言中,map 读写操作不是并发安全,当有多个协程并发读写 map 时,可能会产生读写冲突...可能有读者会有疑问,Golang 官方为什么不把 map 设计为原生支持并发读写

    4K20

    锦囊篇|一文摸懂OkHttp

    为什么这两个一起讲解?因为两个构造方式相同OkHttpClient是一个全局掌控者,Request是一个请求体封装。...那好,我们就认定了它是我们CachedThreadPool线程池。 ok!fine!用线程池来进行异步操作,那肯定就是说明里面有一个线程了,那这个线程是啥,我们是否心里有点数?...咋就没看到responseCallback()onResponse方法使用??? 那我们做一个猜测吧,其实看了一下基本也是正解了。...我们不是Runnable嘛,数据是放在线程池中run()来运行,那么onResponse()方法出现应该是在run()这个函数中了。...其实他就是通过一堆拦截器来获取数据,但是显然这里不是终点站,因为我们看到return中就还是一个函数,说明答案还在这个函数中。

    41330
    领券