速通鸿蒙开发!-ArkTs语言基本用法(下)

6.数组

1.常用方法

数组都是 Array 的实例化对象,它提供了很多的 方法来帮助我们快速处理数据

下表列出了一些较为常用方法:

方法名

作用

indexof

判断元素在数组中的索引,不存在返回-1

join

根据传入内容拼接数组,默认为,返回拼接结果,字符串

forEach

遍历数组,并且将数组的每一项作为参数传入到回调函数中,无返回值

map

基于原数组,创建一个新数组

filter

根据回调函数的执行结果,筛选出符合要求的元素,返回一个新数组

find

返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined

findIndex

返回数组中满足条件第一个元素的索引。若没有找到则返回 -1。

every

返回数组中是否每一个元素都符合要求。

some

返回数组中是否有一个元素符合要求。

sort

方法的作用是对原数组的元素进行排序

reduce

数组求和

..........还有一些其他的方法,之后的课程中陆续补充

indexOf() 方法返回数组中第一次出现给定元素的下标,如果不存在则返回 -1。

数组.indexof(要查找的元素)// 存在返回具体下标,不存在返回 -1
-------应用
// 1. 数字数组
const nums = [1,2,3,4,5]
// 2. 字符串数组
const foods = ['西兰花','西葫芦','西兰花']

join()方法将数组用逗号或指定的分隔符,将数组的每一项拼接到一起

数组.join('分隔符') // 基于传入的分隔符 将数组的每一项拼接到一起
数组.join() // 使用【逗号】将数组的每一项 拼接到一起
//试一试
const elements = ['花菜', '西兰花', '菜花']
console.log(elements.join()) // 默认拼接!
console.log(elements.join('')) // 使用''代替,
console.log(elements.join('-')) // 用 - 拼接

forEach() 方法会遍历数组,并且将数组的每一项作为参数传入到回调函数中,无返回值

数组.forEach((数组项:类型,索引:number)=>{
  // 逻辑
})

数组.forEach(数组项=>{
  // 逻辑
})

-------基于提供的数据,通过 forEach 依次打印每一项的 name和 title 属性
// 接口
interface HeroInfo {
  id: number
  name: string
  title: string
}

// 数组
const arr: HeroInfo[] = [
  { id: 105, name: '廉颇', title: '正义爆轰' },
  { id: 106, name: '小乔', title: '恋之微风' },
  { id: 107, name: '赵云', title: '苍天翔龙' },
  { id: 108, name: '墨子', title: '和平守望' },
]
arr.forEach((item:HeroInfo)=>{
  console.log('测试',item.name,item.title)
})

map() 方法创建一个新数组,基于原数组,创建一个新数组(映射)

  1. 如果能推断出类型,泛型参数可以不写
  2. 如果无法推断,需要人为指定类型
数组.map<返回值类型>((数组项,索引)=>{ return xxx })
// 如果返回值的类型编译器无法推断,就需要自行设置
---------应用
// map 基本使用01- 基于numArr返回新数组,每一个数组翻倍
// map 基本使用01- 基于numArr返回新数组,每一个数组翻倍,并转为字符串
const numArr: number[] = [1, 2, 3, 4, 5]
const numArr2: number[] = numArr.map((v => {
  return v * 2
}))
const strArr: string[] = numArr.map((v => {
  return (v * 2).toString()
}))


// map 基本使用03 - 基于 foodArr 返回新数组,每一项 都是一个对象
// name 为食物名,price 为5-10 的随机价格 ,比如{ name:'西兰花',price:10 }
interface FoodInfo {
  name: string
  price: number
}

const foodArr: string[] = ['西兰花', '西葫芦', '西红柿', '西北风']
foodArr.map<FoodInfo>((v => {
  return {
    name: v,
    price: Math.random() * 11 + 5
  }
}))

根据回调函数的执行结果,筛选出符合要求的元素,返回一个新数组

数组.filter((数组项:类型,索引:number)=>{
  return true  // 或者可以解析为 true 的值   需要这一项
  return false // 或者可以解析为 false 的值  不需要这一项
})
--------应用
// filter基本使用 01 - 筛选出大于 5 的数
const nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

const res1 = nums.filter((item: number, index: number) => {
  if (item > 5) {
    return true
  } else {
    return false
  }
})
console.log('筛选之后的结果是:', res1)


interface Food {
  name: string
  price: number
}

// filter基本使用 02 - 筛选出价格大于 5 的食物
const foods: Food[] = [
  {
    name: '西兰花',
    price: 6
  },
  {
    name: '西红柿',
    price: 3
  },
  {
    name: '榴莲',
    price: 30
  },
  {
    name: '葱花',
    price: 1
  }
]
const res2 = foods.filter((item: Food, index: number) => {
  if (item.price > 5) {
    return true
  } else {
    return false
  }
})
// 复杂类型的数据(对象,对象数组),可以通过 JSON.stringify()转为 字符串进行打印
console.log('筛选之后的食物:', JSON.stringify(res2))

方法就地对数组的元素进行排序,并返回对相同数组的引用。排序是改变原数组

// 自定义排序规则
数组.sort((第一个比较元素,第二个比较元素)=>{
  return 大于0 值 // a 会调换到 b 的后面
  return 小于0 值 // a 会继续留在 b 的前面
  return 0 // 不变
})
------------------------应用
// 数值数组排序
const arr = [5, 12, 8, 130, 44]

arr.sort((a,b)=>{
  // return a-b
  return b-a
})
console.log(arr.toString())

interface Food{
  name:string
  price:number
}

// 对象数组排序
const foods:Food[] = [
  {
    name: '西兰花',
    price: 6
  },
  {
    name: '西红柿',
    price: 3
  },
  {
    name: '榴莲',
    price: 30
  },
  {
    name: '葱花',
    price: 1
  }
]
foods.sort((a,b)=>{
  return a.price-b.price
})
console.log(JSON.stringify(foods))

reduce方法的作用是求和,他会逐个遍历数组元素,每一步都将当前元素的值与前一步的结果相加

// 纯数值类数组求和
reduce((上一次累加结果,当前元素值)=>{})
// 对象数组求和
reduce((上一次累加结果,当前元素值)=>{}, 初始值)


// 数值数组排序
const arr = [5, 12, 8, 130, 44]

const res = arr.reduce((a, b) => {
  // return a-b
  return a + b
})
console.log('res:', res)

interface Food {
  name: string
  price: number
  count: number
}

// 对象数组排序
const foods: Food[] = [
  {
    name: '西兰花',
    price: 6,
    count: 2
  },
  {
    name: '西红柿',
    price: 3,
    count: 3
  },
  {
    name: '榴莲',
    price: 30,
    count: 2
  },
  {
    name: '葱花',
    price: 1,
    count: 10
  }
]
const total = foods.reduce((a, b) => {
  return a + b.price * b.count
}, 0)
console.log('total:', total)

findIndex() 方法返回数组中满足提供的测试函数的第一个元素的索引。若没有找到对应元素则返回 -1

// 索引,如果用不上可以省略不写
数组.findIndex((数组项:类型,索引:number)=>{
  return true  // 找到了需要的元素
  return false // 或者可以解析为 false 的值  不是这一项
})
// 1. 字符串数组
const arr = ['西兰花', '西葫芦', '西兰花']

arr.findIndex((item: string, index: number) => {
  if (item == '西葫芦') {
    return true
  } else {
    return false
  }
})

find() 方法返回通过测试(函数内判断)的数组的第一个元素的值,找不到返回 undefined

// 索引,如果用不上可以省略不写
数组.find((数组项:类型,索引:number)=>{
  return true  // 找到了需要的元素
  return false // 或者可以解析为 false 的值  不是这一项
})

// 1. 字符串数组
const arr = ['西兰花', '西葫芦', '西兰花']

let idx:string|undefined = arr.find((item: string, index: number) => {
  if (item == '西葫芦') {
    return true
  } else {
    return false
  }
})
console.log('测试',idx)//测试 西葫芦

every 方法方测试一个数组内的【所有元素】是否都能通过指定函数的测试。它返回一个布尔值

// 索引,如果用不上可以省略不写
const res = 数组.every((数组项:类型,索引:number)=>{
  return true  // 当前元素符合要求 返回 true
  return false // 当前元素不符合要求 返回 false
})
// res 可以获取是否每个元素都符合要求
-----------应用
// 1. 数值数组 判断是否每个元素都大于 2
const numArr:number[] = [2,4,6,8,10]
let res:boolean = numArr.every((item:number)=>{
  return item>2
})
console.log('测试',res)
// 2. 字符串数组 判断是否每个元素里面都有绿字
const foodArr:string[] = ['绿茶','绿豆','绿色能源','绿色心情','茉莉奶绿']
let res2:boolean = foodArr.every((item:string)=>{
  return item.includes('绿')
})
console.log('测试',res2)

some 方法测试数组中是否【至少有一个元素】通过了由提供的函数实现的测试。

// 索引,如果用不上可以省略不写
const res = 数组.every((数组项:类型,索引:number)=>{
  return true  // 当前元素符合要求 返回 true
  return false // 当前元素不符合要求 返回 false
})
// res 可以获取是否 【至少有一个元素】符合要求
--------应用
// 1. 数值数组 判断是否每个元素都大于 2
const numArr:number[] = [2,4,6,8,10]
let res:boolean = numArr.some((item:number)=>{
  return item>2
})
console.log('测试',res)
// 2. 字符串数组 判断是否每个元素里面都有绿字
const foodArr:string[] = ['绿茶','绿豆','绿色能源','绿色心情','茉莉奶绿']
let res2:boolean = foodArr.some((item:string)=>{
  return item.includes('张三')
})
console.log('测试',res2)

7.对象

1.常用内置对象
1.Math对象

是一个内置对象,它拥有一些数学常数属性和数学函数方法。Math 的所有属性与方法都是静态的,使用的时候直接通过Math点出来即可

常用方法

方法

说明

Math.random()

返回一个 0 到 1 之间的伪随机数。

Math.ceil(x)

返回大于一个数的最小整数,即一个数向上取整后的值。

Math.floor(x)

返回小于一个数的最大整数,即一个数向下取整后的值。

Math.round(x)

返回四舍五入后的整数。

Math.abs(x)

返回一个数的绝对值

Math.max([x[,y[, …]]])

返回零到多个数值中最大值。

Math.min([x[,y[, …]]])

返回零到多个数值中最小值。

Math.Pi

圆周率,一个圆的周长和直径之比,约等于 3.14159。

....更多内容参考文档

const numA: number = 1.5
console.log(Math.ceil(numA) + '') // 向上取整 2
console.log(Math.floor(numA) + '') // 向下取整 1
console.log(Math.round(numA) + '') // 四舍五入 2

const numB:number = -9
console.log(Math.abs(numB) + '') // 绝对值 9

const numList: number[] = [13, 2, 31, 42, 15, 56, 27, 28]
const max: number = Math.max(...numList)
const min: number = Math.min(...numList)
console.log('max:', max) // 最大值
console.log('min:', min) // 最小值

// 0-1 取得到0,取不到 1
console.log(Math.random() + '')

// 返回 0-n的随机数的函数
function getRandomArbitrary(max: number): number {
  return Math.floor(Math.random() * (max + 1))
}

// 返回 min-max 的随机数的函数
function getRandomIntInclusive(min: number, max: number): number {
  return Math.floor(Math.random() * (max - min + 1)) + min; //含最大值,含最小值
}
2.Date对象

ArkTS 中另外一个常用的内置对象 Date,他可以用来创建、解析、操作日期和时间。

使用 Date 对象首先需要通过 new 操作符进行实例化

// 获取当前日期
const date1: Date = new Date()

// 获取指定日期
// ISO 8601 格式(YYYY-MM-DDTHH:mm:ss.ssZ)中间用 T 分隔
const date2: Date = new Date('1995-01-01T01:11:00')
// Unix时间戳 是指从1970年1月1日(UTC)开始到现在经历的时间(毫秒)
const date3: Date = new Date(1706170405708)

实例方法

方法名

作用

说明

getFullYear

获取年份

4 位数年份

getMonth

获取月份

取值 0-11

getDate

获取日期

月份中的日期

getHours

获取小时

getMinutes

获取分钟

getSeconds

获取秒

getDay

获取星期

周日为 0

静态方法

方法名

作用

说明

now

获取当前时间

时间戳

// 大伙执行的时候 即可获取到时间戳啦~
console.log(Date.now()+'')
2.String 字符串对象

String 提供了不少的方法让我们来处理字符,咱们来看几个常用的

split() 方法根据传入的内容将字符串分隔为数组

字符串.split(分隔符)// 返回切割之后的数组
--------试一试
// 1. 切割为数组
const branchFilter: string = ' 全部分路  | 对抗路 |   中路  | 发育路  | 游走 | 打野 '
console.log('测试',branchFilter.split('|'))
// 全部分路  , 对抗路 ,   中路  , 发育路  , 游走 , 打野

const tabFilter: string = '  所有段位  - 巅峰赛1350+ -   顶端排位 - 赛事  '
console.log('测试',tabFilter.split('-'))
// 所有段位  , 巅峰赛1350+ ,   顶端排位 , 赛事

// 2. 获取日期
const dateStr:string =  '2024-04-27'
console.log('测试',dateStr.split('-'))
//2024,04,27

trim方法会从字符串的两端移除空白字符,并返回一个【新的字符串】,而不会修改原始字符串。

字符串.trim()// 返回去除空格之后的字符串

// trim 去除两边空格
// 1.基础文本
const str: string = '   123   '
console.log(str.trim()) // 123
// 2.用户名
const username = '  jack  '
// 3.密码
const password = ' 1234abc '

toLowerCase() 方法将该字符串转换为小写形式。toUpperCase() 方法将该字符串转换为大写形式。

字符串.toLowerCase()// 返回转为小写之后的字符串
字符串.toUpperCase()// 返回转为大写之后的字符串
-----------应用场景
// toLowerCase 转小写 toUpperCase 转大写
// 1.验证码
const code = '1a2C'
// 2.带后缀名的文件信息
const filename = 'abc.PNG'
// 3.编程语言中的关键字
const boolStr = 'true'

includes() 方法执行区分大小写的搜索,以确定是否可以在一个字符串中找到另一个字符串,并根据情况返回 true 或 false。

字符串.includes(查询的字符串)// 返回判断结果 true / false
-------------------应用场景
// includes 方法 判断是否存在特定字符
// 1. 判断是否有@符号
const emailStr = 'user@example.com'

// 2.判断是否为gif文件
const fileName = 'dance.gif'

// 3.判断密码中是否有下划线
const pass = 'itheima-123'

// 4.判断是否有特定词汇 ,比如 牛逼 最 等
const comment = `杭州是一个令人惊叹的地方,我刚刚度过了一个超牛逼的旅行。
西湖的景色太美了,特别是在夕阳西下时,湖水波光粼粼,真是美得不像话。
还去了灵隐寺,感受到了古老的气息和庄严的氛围,让我心生敬意。
在杭州还尝了最正宗的龙井茶和小笼包,老牛逼了!
最喜欢的是游览乌镇古镇,那里的古建筑和石板路让我仿佛穿越回古代。这次旅行真是太棒了,杭州是个值得一游的地方!`

slice方法提取字符串的一部分,并将其作为新字符串返回,而不修改原始字符串。

字符串.slice(起始索引)// 从起始索引切割到末尾
字符串.slice(起始索引,结束索引) // 从起始索引,切换到结束索引
----------应用场景
// slice方法
// 1. 提取 逗号 之后的内容
const str1 = 'hi,你好吗?'

// 2. 提取 中午
const str2 = '今天中午吃的是西兰花炒蛋'

8.正则表达式

1.概述

正则表达式是用于匹配字符串中字符组合的模式(规则)

日常开发中主要用来做三件事:匹配、替换、提取

  • 手机号表单要求用户只能输入11位的数字 (匹配)
  • 过滤掉页面内容中的一些敏感词(替换)
  • 从字符串中获取我们想要的特定部分(提取)等
2.基本使用
// 方式 1:简写
const res1: RegExp = /ArkTS/
// 方式 2:通过实例化的方式创建
const reg2: RegExp = new RegExp('ArkTS')

console.log('web:', res1.test('ArkTS')) // true
console.log('web:', res1.test('Java')) // false
3.元字符

元字符指的是在正则表达式中,有特殊含义的符号

正则表达式中绝大多数的字符都是描述他们本身,比如:
/ArkTS/ // 表示 ArkTS 这 5 个字母
有一些具有特殊含义的字符,可以极大的提高正则表达式的灵活性和功能,比如:
/[a-z]/   // 只能是 a-z中的字母

像上面的 [] , - 就是元字符,接下来咱们来看看有哪些常用的元字符

1.边界符

正则表达式中的边界符(位置符)用来提示字符所处的位置,主要有两个字符

边界符

说明

^

表示匹配行首的文本(以谁开始)

$

表示匹配行尾的文本(以谁结束)

如果 ^ 和 $ 在一起,表示必须是精确匹配

// 元字符之边界符
// 1. 匹配开头的位置 ^
const reg = /^ArkTS/
console.log('res:', reg.test('ArkTS语法')) //true
console.log('res:', reg.test('学习ArkTS')) //false
console.log('res:', reg.test('学习ArkTS语法')) //false
console.log('res:', reg.test('Ar')) //false

// 2. 匹配结束的位置 $
const reg1 = /ArkTS$/
console.log('res1:', reg1.test('ArkTS语法')) //false
console.log('res1:', reg1.test('学习ArkTS')) //true
console.log('res1:', reg1.test('学习ArkTS语法')) //false
console.log('res1:', reg1.test('Ar')) //false

// 3. 精确匹配 ^ $
const reg2 = /^ArkTS$/
console.log('res2:', reg2.test('ArkTS语法')) //false
console.log('res2:', reg2.test('学习ArkTS')) //false
console.log('res2:', reg2.test('学习ArkTS语法')) //false
console.log('res2:', reg2.test('ArkTS')) //true
console.log('res2:', reg2.test('Ar')) //false
console.log('res2:', reg2.test('ArkTSArkTS')) //false
2.量词

量词用来设定某个模式的重复次数

量词

说明

*

重复零次或更多次

+

重复一次或更多次

?

重复零次或一次

{n}

重复 n 次

{n,}

重复 n 次或更多次

{n,m}

重复 n 到 m 次

// 元字符之量词
// 1. * 重复次数 >= 0 次
const reg1 = /^w*$/
console.log('res:', reg1.test('')) //true
console.log('res:', reg1.test('w')) //true
console.log('res:', reg1.test('ww')) //true
console.log('res:', '-----------------------')

// 2. + 重复次数 >= 1 次
const reg2 = /^w+$/
console.log('res:', reg2.test('')) //false
console.log('res:', reg2.test('w')) //true
console.log('res:', reg2.test('ww')) //true
console.log('res:', '-----------------------')

// 3. ? 重复次数  0 || 1
const reg3 = /^w?$/
console.log('res:', reg3.test('')) //true
console.log('res:', reg3.test('w')) //true
console.log('res:', reg3.test('ww')) //false
console.log('res:', '-----------------------')


// 4. {n} 重复 n 次
const reg4 = /^w{3}$/
console.log('res:', reg4.test('')) //false
console.log('res:', reg4.test('w')) //false
console.log('res:', reg4.test('ww')) //false
console.log('res:', reg4.test('www')) //true
console.log('res:', reg4.test('wwww')) //false
console.log('res:', '-----------------------')

// 5. {n,} 重复次数 >= n
const reg5 = /^w{2,}$/
console.log('res:', reg5.test('')) //false
console.log('res:', reg5.test('w')) //false
console.log('res:', reg5.test('ww')) //true
console.log('res:', reg5.test('www')) //true
console.log('res:', '-----------------------')

// 6. {n,m}   n =< 重复次数 <= m
const reg6 = /^w{2,4}$/
console.log('res:', reg6.test('w')) //false
console.log('res:', reg6.test('ww')) //true
console.log('res:', reg6.test('www')) //true
console.log('res:', reg6.test('wwww')) //true
console.log('res:', reg6.test('wwwww')) //false
3.范围

表示字符的范围,定义的规则限定在某个范围,比如只能是英文字母,或者数字等等,用表示范围

范围

说明

[abc]

匹配包含的单个字符。也就是只有a ll b ll c 这三个单字符返回true,可以理解为多选1

[a-z]

连字符。来指定字符范围。[a-z]表示 a到226个英文字母

[^abc]

取反符。[^a-z]匹配除了小写字母以外的字符

// 元字符之范围  []
// 1. [abc] 匹配包含的单个字符, 多选1
const reg1 = /^[abc]$/
console.log('res:', reg1.test('a')) //true
console.log('res:', reg1.test('b')) //true
console.log('res:', reg1.test('c')) //true
console.log('res:', reg1.test('d')) //false
console.log('res:', reg1.test('ab')) // false
console.log('测试','--------------------------')
// 2. [a-z] 连字符 单个
const reg2 = /^[a-z]$/
console.log('res:', reg2.test('a')) //true
console.log('res:', reg2.test('p')) //true
console.log('res:', reg2.test('0')) //false
console.log('res:', reg2.test('A')) //false
console.log('测试','-------------------------')
// 3. [^a-z] 取反符
const reg5 = /^[^a-z]$/
console.log('res:', reg5.test('a')) //false
console.log('res:', reg5.test('A')) //true
console.log('res:', reg5.test('么')) //true
console.log('测试','-------------------------')

// 4.想要包含小写字母,大写字母 ,数字
const reg3 = /^[a-zA-Z0-9]$/
console.log('res:', reg3.test('B')) //true
console.log('res:', reg3.test('b')) //true
console.log('res:', reg3.test('9')) //true
console.log('res:', reg3.test(',')) //false
console.log('测试','-------------------------')

// 5.试一试:用户名可以输入英文字母,数字,可以加下划线,要求 6~16位
const reg4:RegExp =/^[a-zA-Z0-9_]{6,12}$/
console.log('测试',reg4.test('jack_1321'))//true
console.log('测试',reg4.test('1321'))//false
4.字符类

某些常见模式的简写方式,区分字母和数字

字符类

说明

\d

匹配0-9之间的任一数字,相当于[0-9]

\D

匹配所有0-9以外的字符,相当于[^0-9]

\w

匹配任意的字母、数字和下划线,相当于[A-Za-z0-9_]

\W

除所有字母、数字和下划线以外的字符,相当于[^A-Za-z0-9_]

\s

匹配空格(包括換行符、制表符、空格符等),相等于[\t\r\n\v\f]

\S

匹配非空格的字符,相当于[^\t\r\n\v\f]

// 试一试。匹配 1990-10-10 、1990-1-1 这种格式
const reg:RegExp =/^\d{4}-\d{1,2}-\d{1,2}$/

console.log('测试',reg.test('1990'))
console.log('测试',reg.test('1990-1-1'))
console.log('测试','---------------------------')
//完整版日期正则
const reg1:RegExp = /^(19|20)\d{2}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$/
console.log('测试',reg1.test("1990-10-10"));  // true
console.log('测试',reg1.test("1990-1-1"));     // false
console.log('测试',reg1.test("1990-13-01"));  // false
console.log('测试',reg1.test("1990-01-32"));  // false
console.log('测试',reg1.test("2000-02-29"));  // true,这是简单版不能判断闰年
console.log('测试',reg1.test("2004-02-29"));  // true,因为2004年是闰年
5.替换和修饰符

字符串的 replace 方法,可以结合正则进行字符串的替换

默认是不是只能检索一个?

使用正则结合修饰符可以实现大小写区分,是否匹配所有

修饰符

说明

i

单词 ignore 的缩写,正则匹配时字母不区分大小写

g

单词 global 的缩写,匹配所有满足正则表达式的结果

// 检索规则:文本、正则
// 替换内容:文本
// 返回值:替换之后的结果
字符串.replace(检索规则,替换内容)
// 替换和修饰符
const str = '欢迎大家学习ArkTS,相信大家一定能学好ArkTS!!!'
// 将 ArkTS 替换位 鸿蒙开发咋写? 分别用正则和字符串作为检索规则
--------------试一试
// 替换和修饰符
const str = '欢迎大家学习ArkTS,相信大家一定能学好ArkTS!!!'
// replace 返回值是替换完毕的字符串
console.log(str.replace(/arkts/, '鸿蒙开发')) //欢迎大家学习ArkTS,相信大家一定能学好ArkTS!!!
console.log(str.replace(/arkts/i, '鸿蒙开发')) // 欢迎大家学习鸿蒙开发,相信大家一定能学好ArkTS!!!
console.log(str.replace(/arkts/gi, '鸿蒙开发')) //欢迎大家学习鸿蒙开发,相信大家一定能学好鸿蒙开发!!!
console.log(str.replace(/arkts/ig, '鸿蒙开发')) //欢迎大家学习鸿蒙开发,相信大家一定能学好鸿蒙开发!!!

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值