ErLang语法提要收藏

【100%通过率】华为OD机试真题 JS 实现【水库蓄水问题】【2023 Q1 | 100分】 给定一个长度为 n 的整数数组height。数组的元素表示山的高度,选择两个元素作为水库的边界,求蓄水量的最大值并输出蓄水量最大时的边界下标(蓄水量相同时输出下标较近的)。 阅读详情
  ErLang语法提要收藏

新一篇: erlang网络编程的几个性能调优和注意点 | 旧一篇: .NET Rocks上值得花时间了解的一些技术信息

ErLang中的标点符号
ErLang语法中充满了一些约定。大写字母开头的名字(比如Address),表示一个变量,包括参数、局部变量等;小写字母开头的单词(比如ok),表示一个常量,叫做atom(原子的意思),包括常量名、函数名、模块名等。
ErLang的注释用%开头。ErLang用下划线“_”表示任意变量,类似于Java的switch语法里面的default选项。
ErLang脱胎于Prolog,不过,我觉得,ErLang语法和Haskell语法比较象,都是采用 -> 定义函数。
ErLang语句中的标点符号用法很象文章的标点符号。
整个函数定义结束用一个句号“.”;同一个函数中,并列的逻辑分支之间,用分号“;”分界;顺序语句之间,用逗号“,”分隔。
ErLang中,{ }不是表示程序块的开头和结尾,而是表示一种特殊的数据结构类型——Tuple(元组),比如,{12, 3, ok}。我们可以把Tuple理解为定长数组。
[ ] 则表示最基本的函数式编程的数据结构类型——List。List数据结构很基本,写法和用法也有一定的复杂度,不是表面上看起来那么简单,后面讲解Closure的章节会详细介绍List的最基本的构造原理。
下面我们来看一个简单的例子。
我们首先定义一个最简单的函数,把一个参数乘以10,然后加1。
times10( Number ) –>
Temp = 10 * Number,
Temp + 1.

为 了说明问题,上面的代码把乘法操作和加法操作分成两个步骤。Temp = 10 * Number语句后面是逗号,因为这是两条顺序执行的语句。Temp + 1语句后面是句号,表示整个函数定义结束。而且,可以看出,ErLang没有return语句,最后执行的那条语句的执行结果就是返回值。
下面,我们把这个函数优化一下。当参数等于0的时候,直接返1;否则,就乘以10,然后加1,然后返回。这时候,我们就要用到case of逻辑分支语句,相当于java的switch语句。
times10( Number ) –>
case Number of
0 -> 1;
_ ->
Temp = 10 * Number,
Temp + 1
end.

我们来仔细观察这段ErLang程序。
当Number等于0的时候,直接返回1。由于这是一条分支语句,和后面的分支是并列的关系,所以,1的后面的标点符号是分号。后面这个分支,下划线“_”表示任何其它值,这里就表示除了1之外的任何其它数值。
需要注意的一点是,case of语句需要用end结尾,end之前不需要有标点符号。
上述代码中的case of 语句,其实就是Pattern Match的一种。ErLang的Pattern Match很强大,能够大幅度简化程序逻辑,后面进行专门介绍。
Pattern Match
Pattern Match主要有两个功能——比较分派和变量赋值。
其中,比较分派是最主要的功能。比较分派的意思是,根据参数值进行条件分支的分派。可以把比较分派功能看作是一种类似于if, else等条件分支语句的简洁强大写法。
上面的例子中,case Number of 就是根据Number的值进行比较分派。更常见的写法是,可以把Pattern Match部分提到函数定义分支的高度。于是,上述代码可以写成下面的形式:
times10( 0 ) –> 1;
times10( Number ) –>
Temp = 10 * Number,
Temp + 1.

这段代码由两个函数定义分支构成,由于两个函数分支的函数名相同,而且参数个数相同,而且两个函数定义分支之间采用分号“;”分隔,说明这是同一个函数的定义。函数式编程语言中,这种定义方式很常见,看起来形式很整齐,宛如数学公式。
这段代码的含义是,当参数值等于0的时候,那么,程序走第一个函数定义分支(即分号“;”结尾的“times10( 0 ) –> 1;”),否则,走下面的函数定义分支(即“times10( Number ) –>…”)。
第二个分支中的参数不是一个常数,而是一个变量Number,表示这个分支可以接受任何除了0之外的参数值,比如,1、2、12等等,这些值将赋给变量Number。
因此,这个地方也体现了Pattern Match的第二个功能——变量赋值。

Pattern Match的形式可以很复杂,下面举几个典型的例子。
(1)数据结构拆解赋值
前面将到了ErLang语言有一种相当于定长数组的Tuple类型,我们可以很方便地根据元素的位置进行并行赋值。比如,
{First, Second} = {1, 2}
我们还可以对复合Tuple数据结构进行赋值,比如
{A, {B, C}, D} = { 1, {2, 3}, 4 }
List数据结构的赋值也是类似。由于List的写法和用法不是那么简单,三言两语也说不清楚,还徒增困扰,这里不再赘述。
(2)assertEquals语句
在Java等语言中,我们写单元测试的时候,会写一些assert语句,验证程序运行结果。这些assert语句通常是以API的方式提供,比如,assertTrue()、assertEquals()等。
在ErLang中,可以用简单的语句达到类似于assertTrue()、assertEquals()等API的效果。
比如,ErLang中,true = testA() 这样的语句表示testA的返回结果必须是true,否则就会抛出异常。这个用法很巧妙。这里解释一下。
前面讲过,ErLang语法约定,小写字母开头的名字,都是常量名。这里的true自然也是一个常量,既然是常量,我们不可能对它赋值,那么true = testA()的意思就不是赋值,而是进行匹配比较。
(3)匹配和赋值同时进行
我们来看这样一段代码。
case Result of
{ok, Message} -> save(Message);
{error, ErrorMessage} -> log(ErrorMessage)
end.

这段代码中,Result是一个Tuple类型,包含两个元素,第一个元素表示成功(ok)或者失败(error),第二个元素表示具体的信息。
可以看到,这两个条件分支中,同时出现了常量和变量。第一个条件分支中的ok是常量,Message是变量;第二个条件分支中的error是常量,ErrorMessage是变量。
这 两个条件分支都既有比较判断,也有变量赋值。首先,判断ResultTuple中的第一个元素和哪一个分支的第一个元素匹配,如果相配,那么把 ResultTuple中的第二个元素赋给这个分支的第二个变量元素。即,如果Result的第一个元素是ok,那么走第一个条件分支,并且把 Result的第二个元素赋给Message变量;如果Result的第二个元素是error,那么走第二个条件分支,并且把Result的第二个元素赋 给ErrorMessage变量。

在Java等语言中,实现上述的条件分支逻辑,则需要多写几条语句ErLang语法可以从形式上美化和简化逻辑分支分派复杂的程序。
除了支持数相等比较,Pattern Match还可以进行范围比较、大小比较等,需要用到关键字when,不过用到when的情况,就比if else简洁不了多少,这里不再赘述。
匿名函数
ErLang允许在一个函数体内部定义另一个匿名函数,这是函数式编程的最基本的功能。这样,函数式语言才可以支持Closure。我们来看一个ErLang的匿名函数的例子。
outer( C ) –>
Inner = fun(A, B) -> A + B + C end,
Inner(2, 3).

这 段代码首先定义了一个命名函数outer,然后在outer函数内部定义了一个匿名函数。可以看到,这个匿名函数采用关键字fun来定义。前面讲过,函数 式编程的函数就相当于面向对象编程的类实例对象,匿名函数自然也是这样,也相当于类实例,我们可以把这个匿名函数赋给一个变量Inner,然后我们还可以 把这个变量当作函数来调用,比如,Inner(2, 3)。
fun是ErLang用来定义匿名函数的关键字。这个关键字很重要。fun定义匿名函数的用法不是很复杂,和命名函数定义类似。
函数分支的定义也是类似,只是需要用end结尾,而不是用句号“.”结尾,而且fun只需要写一次,不需要向命名函数那样,每个分支都要写。比如,
MyFunction = fun(0) -> 0;
(Number) -> Number * 10 + 1 end,
MyFunction(3),
函数作为变量
匿名函数可以当作对象赋给变量,命名函数同样也可以赋给变量。具体用法还是需要借助重要的fun关键字。比如,
MyFunction = fun outer / 1

就可以把上述定义的outer函数赋给MyFunction变量。后面的 / 0表示这个outer函数只有一个参数。因为ErLang允许有多个同名函数的定义,只要参数个数不同,就是不同的函数。
我们可以看到,任何函数都可以作为变量,也可以作为参数和返回值传来传去,这些变量也可以随时作为函数进行调用,于是就具有了一定的动态性。
函数的动态调用
ErLang有一个apply函数,可以动态调用某一个函数变量。
基本用法是 apply( 函数变量,函数参数列表 )。比如,上面的MyFunciton函数变量,就可以这么调用,apply( MyFunction, [ 5 ])。
那么我们能否根据一个字符串作为函数名获取一个函数变量呢?这样我们就可以根据一个字符串来动态调用某个函数了。
ErLang 中,做到这一点很简单。前面讲过,函数名一旦定义了,自然就固定了,这也类似于常量名,属于不可变的atom(原子)。所有的atom都可以转换成字符 串,也可以从字符串转换过来。ErLang中的字符串实质上都是List。字符串和atom之间的转换通过list_to_atom和 atom_to_list来转换。
于是我们可以这样获取MyFunciton:MyFunction = list_to_atom(“outer”)
如果outer函数已经定义,那么MyFucntion就等于outer函数,如果outer函数没有定义,那么list_to_atom(“outer”)会产生一个新的叫做outer的atom,MyFucntion就等于这个新产生的atom。
如果需要强制产生一个已经存在的atom,那么我们需要调用list_to_existing_atom转换函数,这个函数不会产生新的atom,而是返回一个已经存在了的atom。
Tuple作为数据成员集合
前面讲解函数式编程特性的时候,提到了函数式编程没有面向对象编程的成员变量,这是一个限制。
ErLang的Tuple类型可以一定程度克服这个限制。Tuple可以一定程度上担当容纳成员变量的职责。
面向对象的类定义,其实就是一群数据和函数的集合,只是集合的成员之间都有一个this指针相关联,可以相互找到。
ErLang的Tuple类型就是数据的集合,可以很自然地发挥成员变量的作用,比如,{Member1, Member2}。
读者可能会说,ErLang的函数也可以作为变量,也可以放到Tuple里面,比如, { Memer1, Member2, Funtion1, Function2}。这不就和面向对象编程一样了吗?
遗憾的是,这样做是得不偿失的。因为函数式编程没有面向对象的那种内在的this指针支持,自然也没有内在的多态和继承支持,硬把数据和函数糅合在一个Tuple里面,一点好处都没有,而且还丧失了函数作为实例对象的灵活性。
所 以,函数式编程的最佳实践(Best Practice)应该是:Tuple用来容纳成员数据,函数操作Tuple。Tuple定义和函数定义加在一起,就构成了松散的数据结构,功能上类似于 面向对象的类定义。Tuple + 函数的数据结构,具有多态的特性,因为函数本身能够作为变量替换;但是不具有继承的特性,因为没有this指针的内在支持。
正是因为 Tuple在数据类型构造方面的重大作用,所以,ErLang专门引入了一种叫做Record的宏定义,可以对Tuple的数组下标位置命名。比如,把第 一个元素叫做Address,第二个元素叫做Zipcode,这样程序员就可以这些名字访问Tuple里面的元素,而不需要按照数组下标位置来访问。
Tuple和Record的具体用法还是有一定复杂度,限于篇幅,本章没有展开说明,只提了一些原理方面的要点。
其它
ErLang还有其它语法特性和细节,不再一一赘述。有兴趣的读者,可以自行去ErLang网站(www.erlang.org)进行研究。  

发表于 @ 2008年01月24日 14:27:00|评论(0)|编辑

新一篇: erlang网络编程的几个性能调优和注意点 | 旧一篇: .NET Rocks上值得花时间了解的一些技术信息 

微信小程序 - [wxapplib]] backgroundfetch privacy fail {“errno”:101,“errMsg”:“private_getBackgroundFetchDa 微信小程序报错之backgroundfetch privacy fail,微信小程序报错WAServiceMainContext.js:1 [wxapplib]] backgroundfetch privacy fail {“errno“:101,怎么解决?问题出现:调用wx.chooseMessageFile报错(开发者工具中正常)用户隐私协议中未声明小程序使用此功能,安卓真机调试报错:backgroundfetch privacy fail ,怎么解决?微信小程序[wxapplib]] backgrou 阅读详情

相关推荐

从零到一:手把手部署用友T3标准版11.2及SQL Server 2008R2环境

本文详细介绍了从零开始部署用友T3标准版11.2及SQL Server 2008R2环境的完整流程,包括环境准备、SQL Server安装、环境检测与修复、T3标准版安装实战以及初始化配置与测试。通过手把手的步骤指导和常见问题解决方案,帮助用户顺利完成部署,确保系统稳定运行。

weixin_28339967的博客 454

ErLang语法提要

ErLang语法提要 ErLang中的标点符号 ErLang语法中充满了一些约定。大写字母开头的名字(比如Address),表示一个变量,包括参数、局部变量等;小写字母开头的单词(比如ok),表示一个常量,叫做atom(原子的意思),包括常量名、函数名、模块名等。 ErLang的注释用%开头。ErLang用下划线“_”表示任意变量,类似于Java的switch语法里面的default选项...

buaawhl的专栏 411

扫地机器人全场景测试实战:从实验室到真实家庭的可靠性验证

本文深入探讨了扫地机器人从实验室到真实家庭的全场景测试方法,揭示了软硬件测试中的关键挑战。通过分析场景化测试的重要性,文章详细介绍了硬件耐久性、软件稳定性和环境适应性三大测试维度,并提供了真实家庭测试的实用方法论。消费者可重点关注清洁率、覆盖率等核心指标,同时了解测试工程师的私房建议,帮助选择更可靠的扫地机器人产品。

hhh00的博客 1076

erlang 单元测试

erlang 单元测试 learn you some erlang for great good 欧盟国家委员会 测试的需要 我们编写的软件随着时间的推移变的越来越大,越来越复杂. 当发生这种情况时,启动 Erlang shell, 输入内容,查看结果以及确保代码更改后,能够正常工作. 随着时间的推移,每个人都可以更加简单的运行之前准备好的测试代码,而不是一直按照清单去手工检查软件里的所有测...

keep it simple,stupid 1377

从原理到实践:手把手教你如何校准和使用六维力传感器(附常见问题排查)

本文详细解析六维力传感器的工作原理与校准方法,提供从选型到故障排查的完整指南。重点介绍电阻式与电容式技术对比、六步校准法实战以及温度补偿技巧,帮助工程师精准测量空间力场。适用于机器人触觉反馈、航空航天测试等高精度场景。

weixin_29309475的博客 386

【知识点讲解】大模型参数量与计算量(FLOPs)估算方法

指标参数量 (Params)计算量 (FLOPs)含义模型的大小,静态模型的计算复杂度,动态决定因素模型结构(宽度、深度)模型结构 +输入数据(B, S)影响内存占用、磁盘空间运行速度、能耗单位M (百万), B (十亿)工具thopptflopstorchinfothopptflopsfvcore重要提示FLOPs ≠ 速度:FLOPs 是理论计算量。实际速度还受内存带宽 (Memory Bandwidth)并行度硬件架构等因素严重影响。

AI浩 2096

Erlang学习笔记(5) -- 断言, when / case of / if

学习用的书籍是这个 http://book.douban.com/subject/3260311/断言: 将断言分开的逗号(,)表示and(与)操作; 将断言分开的分号(;)表示or(或)操作。 断言表达式合法的语法形式: 1)原子true 2)其他常量,这些在断言表达式中都会被求值为false 3)断言谓词或者断言BIF 4)比较表达式 5)算数表达式 6)布尔表达式 7)短路

pengdong17的专栏 1987

基于 ESP32 的智慧图书馆图书定位与借阅管理系统

本文设计的基于 ESP32 的智慧图书馆图书定位与借阅管理系统,以低成本、模块化、易部署为核心优势,融合 UWB 精准定位、RFID 自动识别、WiFi 无线通信技术,解决了传统图书馆的痛点问题。

weixin_42300449的博客 99

通过使用函数pipeline来改善erlang代码中的case of嵌套

通常,在进行业务开发的时候,我们要对传入接口的参数进行层层验证,比如一个注册新用户的过程: 校验用户填写的表单项是否允许为空,格式是否满足要求 检查用户输入的验证码是否与会话中的验证码一致。 检查用户名是否已经存在 对用户信息进行填充和调整(比如密码要将明文加密) 将调整后的用户信息写入到持...

chongyinqian8301的博客 410

大数据领域数据架构的工业互联网数据架构设计

工业互联网作为第四次工业革命的重要驱动力,正在深刻改变传统制造业的生产方式和商业模式。本文旨在探讨工业互联网环境下的大数据架构设计,重点解决工业数据采集、传输、存储、处理和分析等关键环节的技术挑战。工业互联网数据架构的核心组件大数据技术在工业场景下的应用数据治理和质量控制边缘计算与云计算的协同架构背景介绍:建立基本概念和问题域核心架构:详细解析工业互联网数据架构技术实现:通过代码和数学模型展示关键技术实践案例:展示真实场景应用工具资源:推荐实用开发工具和学习资源。

软件工程实践的博客 855

软件需求规格说明书(SRS)深入解析

摘要: SRS(软件需求规格说明书)是定义系统功能、性能与接口的核心文档,为开发、测试、项目管理提供依据。标准结构包括引言、总体描述、功能/非功能需求、接口等模块。撰写需确保清晰、可验证、无歧义,避免模糊术语。示例展示学生注册模块的需求写法,强调性能与安全性要求。推荐使用Confluence、StarUML等工具辅助编写,交付时需包含主文档、原型图及需求跟踪矩阵。SRS应兼具技术性与管理性,作为沟通桥梁和验收标准。

moton2017的博客 2923

erlang学习笔记

Erlang是一门函数式编程语言,具有不可变状态 Erlang的变量是一次性赋值变量(single-assignment variable) 在Erlang里,变量的获得值是一次成功模式匹配操作的结果,=是一个模式匹配操作符 在Erlang里,原子被用于表示常量值,原子是全局性的,以小写字母开头,还可以放在单引号内,一个原子的值就是它本身 元组用于把一些数量固定的项目归组成单一的实体,用大括号括起

不忘初心,方得始终 1625

ArduPilot简介

一,什么是ArduPilot? ArduPilot是一个可信的,多用途的,开源的自动驾驶系统。该系统支持了非常多的交通工具类型,包括多旋翼无人机,传统直升机,固定翼飞行器,船,潜艇,巡逻车等。源码由大型开发者社区的专家和爱好者共同开发和维护。也欢迎更多的开发者加入源码的迭代演进,最好的“打开”方式就是加入开发者团队论坛。该论坛对所有人开放,在这里可以深入感受到开发者们对ArduPilot的热爱。 论坛链接:ArduPilot Discourse 开发者指南:Welcome to the ArduPil

从0到1,突破自己 5452

Erlang概述收藏

 Erlang概述收藏 新一篇: 什么是Python | 旧一篇: Ruby简介 function StorePage(){d=document;t=d.selection?(d.selection.type!=None?d.selection.createRange().text:):(d.getSelection?d.getSelection():);voi

skyremember的专栏 925

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

更改Erlang的工作目录收藏

更改Erlang的工作目录收藏 新一篇: Mnesia启动过程 | 旧一篇: 进入erlang的世界 function StorePage(){d=document;t=d.selection?(d.selection.type!=None?d.selection.createRange().text:):(d.getSelection?d.getSelection

skyremember的专栏 893

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Erlang 是什么

 Erlang 是什么一种“小众”语言(排名50之外) 一种函数式语言 (变量只能赋值一次) 一种动态类型语言(变量类型在运行时决定,代码需要编译后才能执行,与Python,Ruby等不一样) 一种强类型语言 一种面向并发(Concurrency Oriented)的语言  《一场茶杯里的风暴》(刊于《程序员》06年9、10期),《轻松实现可伸缩性,容错性,和负

skyremember的专栏 1万+

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

第一个 Erlang 程序: Ftp 下载客户端收藏

  第一个 Erlang 程序: Ftp 下载客户端收藏 新一篇: 简单的语法高亮 Erlang 编辑器 | 旧一篇: pon 认证错误的一个可能的原因 function StorePage(){d=document;t=d.selection?(d.selection.type!=None?d.selection.createRange().text:):(d.g

skyremember的专栏 928

Erlang 01收藏

 Erlang 01收藏 新一篇: Erlang 02 | 旧一篇: Erlang 02 function StorePage(){d=document;t=d.selection?(d.selection.type!=None?d.selection.createRange().text:):(d.getSelection?d.getSelection():)

skyremember的专栏 760

【erlang】吃螃蟹 rust 开发 erlang nif 的正确方式 rustler

使用rust开发erlang nif,使用rustler开发erlang的nif

undefined 1607

Erlang十分钟快速入门

http://www.matrix.org.cn/resource/article/2007-09-04/2948b459-5ac5-11dc-af81-f34262335978.html Erlang十分钟快速入门 cleverpig 发表于 2007-09-04 16:59:36 作者:cleverpig     来源:Matrix 评论数:16 点击数:

skyremember的专栏 4129

Erlang 语言入门-1收藏

 Erlang 语言入门-1收藏 新一篇: Action | 旧一篇: Erlang 03 function StorePage(){d=document;t=d.selection?(d.selection.type!=None?d.selection.createRange().text:):(d.getSelection?d.getSelection():

skyremember的专栏 871

Erlang技巧备忘

Erlang技巧备忘 1、and or 和andalso orelse的区别 and和or会计算两边的表达式,而andalso和orelse的求值采用短路机制,比如exp1 andalso exp2,当exp1返回false之后,就不会去求值 exp2,而是直接返回false,而exp1 and exp2会对exp1和exp2都进行求值,or...

weixin_34050389的博客 74

进入Erlang的世界

进入Erlang的世界 原创作者: litaocheng   阅读:3299次   评论:9条   更新时间:2009-02-03     收藏   进入Erlang的世界 作为程序员,我们曾经闻听很多“业界动态”,“技术革新&r

Jalunnier的博客 248

深入解析Erlang/OTP Application运行时机制:从启动到监督树的生命周期管理

在分布式系统架构中,应用生命周期管理是确保服务健壮性的核心技术。其核心原理在于通过规范化的启动、配置、依赖管理和进程监督机制,将独立的代码模块组织成可运维的组件单元。这一机制的技术价值在于提供了统一的生命周期控制接口,实现了依赖的拓扑排序和故障隔离,为构建高可用系统奠定了基础。典型的应用场景包括微服务架构中的服务部署、电信领域的软交换系统以及需要热代码升级的实时平台。本文聚焦于Erlang/OTP框架中的Application运行时行为,通过剖析其启动流程、配置管理和监督树集成等核心机制,并结合**运行时启

weixin_30340819的博客 335

Erlang与java的内存架构比较

写的太好了,忍不住收藏,转载http://blog.youkuaiyun.com/shishiqiushia/article/details/50593508 我读了一篇非常非常有趣的文章(JesperWilhelmsson的一篇论文),是关于Erlang虚拟机(Erlang VM)内存管理策略的。我相信对比一下Erlang和java的虚拟机内存管理策略,一定很有意思。        先给从来

两碗面的博客 506

erlang进程监控:link和monitor

erlang进程监控:link和monitor 分类: erlang/mnesia2013-10-27 17:15 322人阅读 评论(0) 收藏 举报 erlang Erlang最开始是为了电信产品而发展起来的语言,因为这样的目的,决定了她对错误处理的严格要求。Erlang除了提供exception,try catch等语法,还支持Link和Monitor两种监控进程的

482
上一篇: sql server sa 密码更改收藏
下一篇: 第一个 Erlang 程序: Ftp 下载客户端收藏
skyremember
博客等级 码龄20年 204粉丝 484原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值