首页
学习
活动
专区
工具
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

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

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

    52710

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

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

    45310

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

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

    51530

    对于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 实现的原理,希望能够继续坚持下去~

    64730

    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; 泛型为什么使用尖括号 为什么泛型要用尖括号(),而不是别的?

    3.3K40

    如何编写高质量的 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。

    37220

    Go Context 详解之终极无惑

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

    4.9K43

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

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

    983130

    锦囊篇|一文摸懂OkHttp

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

    42130

    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 设计为原生支持并发读写呢?

    4.1K20
    领券