scala语法基础 与 数组方法

本文详细介绍了Scala编程语言的基础知识,包括安装配置、与Java的对比、字符串处理、变量与数据类型、运算符、分支结构、循环、数组操作以及函数式编程特性。讲解了Scala的优雅语法、静态编译速度、与Hadoop生态的融合,并通过实例展示了其特有的模式匹配、单例对象、范式和接口等概念。此外,还涵盖了数组的遍历、修改、转换以及集合操作如map、reduce、fold、filter等。
摘要由CSDN通过智能技术生成

scala 语法基础

// 安装与环境变量(windows | lunix)

// idea插件安装与global libraries配置

// scala vs java

1、环境

运行于jvm之上且兼容java

4、特点

优雅:一行抵多行
速度快:静态编译
方便融合hadoop生态圈:spark依赖scala

5、字符串 “”+"" “”"…\n. …"""

返回值		return				最后一行表达式lreturn
访问符		default friendly	default public
默认导入	java . lang .*		java . lang .* ; scala; scala . Predef;
数据类型	基本类型+引用类型	全部引用类型
static		支持				不支持
范式		oOP					OOP+函数式编程
接口		interface			trait
oOP			类和对象			单例对象|同一个文件中同名(伴生类class+伴生对象object(隐式创建))
方法		()表示调用			无参()可以缺省

//变量与数据类型

数据类型			描述
Byte			8位有符号补码整数。数值区间为-128 到127
short			16位有符号补码整数。数值区间为-32768到32767
Int				32位有符号补码整数。数值区间为-2147483648 到2147483647
Long			64位有符号补码整数。数值区间为-9223372036854775808到 9223372036854775807
Float			32位,IEEE 754 标准的单精度浮点数
Double			64位 IEEE 754 标准的双精度浮点数
Char			16位无符号Unicode字符,区间值为U+0000到U+FFFF
String			字符序列
Boolean			true或false
AnyVal			所有基础类型的父类
Unit			表示无值,和其他语言中void等同。用作不返回任何结果的方法的结果类型。Unit只有一个实例值,写成()。
Null			null或空引用,不兼容值类型
Nothing			Nothing类型在scala的类层级的最底端;它是任何其他类型的子类型。
Any				Any是所有其他类的超类
AnyRef			AnyRef类是scala里所有引用类(reference class)的基类
Tuplel~22		(1,...,22)最多22个允许不同类型元素的

不指定类型

	var 变量=值
	val常量=值

值类型决定变量类型

	(自适应类型:自动感知)
	(第一次赋值后类型确定)

声明时必须初始化

变(常)量

	.getclass.getName
	(第一次赋值后类型确定)声明时必须初始化

变(常)量

	.getClass.getName

指定类型

	var/val变量:类型=值
	var e [ : Tuple2 [ Int , string] ] = (1, "henry" )
	println (s"${e._1} lt${e._2 } ")

特殊写法

	var a , c=6		a和c值都为6

/控制台输入输出

	println( "内容")
	println (s"${var / val} \t...")
	var a = Console. readXxx()	### 己过时
	val br = new BufferedReader(new InputstreamReader (System.in) );
	var a = br. readLine () ;

/运算符:

算术:		不支持		++|--
关系:		回java
逻辑:		同java
赋值:		=
### 不支持三目运算符:由分支取代
	var age = 18;
	var mature = if (age>=18)"mature" else "raw"
	println (mature)

//分支结构

单|双|多		if...
强大的模式匹配
### //简单
	var dial = 7;
	var t = dial match {
	case 1=>"充值"
	case 2=>"余额"
	case 3=>"人工"
	case _->"其他"
	println (t)
-------------------------------
	

### //if守卫
	var score = 88;
	var level = score match {
	case _if (score>=90)=>"A"
	case _if (score>=80)=>"B"
	case _if (score>=60)=>"c"
	case->"D"
	println(level)
### //模式守卫
	val rMail = ".*@ \ lw+\ \l. ( com l cn / net l org) ".r
	val rPhone = "1[3-8]\ ld{9} ".r
	val rPid = "\ ld {17}( \ ldl) ".r  
	var cnt = "aa@qq.com"
	println (cnt match {
	case rMail (cnt)=>"mail"
	case rPhone (cnt)=>"phone"
	case rPid (cnt)=>"pid"
	case_ =>"unknown"
	})

### //样例类匹配
	abstract class Message (t :string , msg : string){
		def apply(t: string,msg: string) : Message = new Message(t,msg) { }
	}
	case class PubMsg (t:string,msg:string) extends Message (t,msg)
	case class ToMsg (t:string, to:Array[String] , msg:String) extends Message (t, msg)
	case class PriMsg (t:String,to:string,msg:String) extends Message (t,msg)
	
	var msgl:Message = PubMsg ( "1", "hello")
	var msg2:Message = ToMsg ( "2",Array ("henry" , "pola" ) , "world")
	var msg3 :Message = PriMsg ( "3", "ariel" , "world")
	
	println (msg3 match {
	case PubMsg (t ,msg) =>"PUB"
	case ToMsg (t,toList , msg)->"TOS"
	case PriMsg (t,to, msg) ->"PRI"
	})
	println (msg3 match {
	case _: PubMsg ->"PUB"
	case _: ToMsg ->"TOS"
	case _: PriMsg =>"PRI"
	} )
### /循环
1、不支持continue, break
	while ...
	do. . .while...
	for (i<-min to max){ }
	for (i<-min until max){ }
	for ( i<-min to max;j<-min to max){ }
	for ( i<-min to max; if...; if...) { }
	for (i<-Array lCollection){ }
	val value = for (i<-min to max; if.. .;if.. .) yield i
### //Array
	var arr:Array[T] = ...
	var darr:Array[Array[T]]= ...
	
	var v:T =arr{index}
	val v:T = arr.apply(index)
	val arr:[Array[T]] = arr.take(size:Int) =>从左边去size个元素
	val arr:[Array[T]] = arr.takeRight(size:Int) =>从右边去size个元素
	val arr:[Array[T]] = arr.takeWhile(f:T=>Boolean) =>从左边开始取从第一个满足条件开始到第一个不满足条件结束,如果第一个不满足条件 就直接结束
	
	
	
	arr.update(index,newV)
	val len:Int = arr.size
	val len:Int = arr.size = arr.length
	val arrCopy:Array[T] = arr.clone()
	
	val tarr:Array[B] = arr.map(f:T=>B)
	val tarr:Array[T] = darr.flatten
	var tarr:Array[T] = darr.flatMap(f:T=>B)  => map+flatten
	
	val parr:ParArray[T] = arr.par
	var arr:(Array[T],Array[T]) = arr.partition(f:T=>Boolean)
	var iter:Iterator[Array[T]] = arr.grounped(size:Int) => size : item size per group => sliding(n,n)
	var iter:Iterator[Array[T]] = arr.sliding([size:Int[,n:step default 1])
	var iter:[(K,Array[T])] = arr.groupBy(_[.?|_1|attr])
	
	val value:B = reduce(f:(T,T) => B)
	val value:B = arr.fold[Left](initVal:T)(f:(T,T) =>B)   =>/:
	val value:B = arr.fold[right](initVal:T)(f:(T,T) =>B)	=>:\
	val value:T = arr.sum
	val value:Int = arr.count(f:T=>Boolean)
	val value:T = arr.min
	val value:T = arr.min
	val value:T = arr.minBy(_.?) => T:Tuple | Class
	val value:T = arr.minBy(_.?) => T:Tuple | Class
	val value:B = arr.par.aggregate(initV:B)(map:(T,T)=>B,reduce:(B,B)=>B)   => 速度快(并行)
	
	val map:Map[K,V] = arr.toMap => 通常 T:Tuple2来完成
	
	arr.foreach(f:T=>Unit)  => 一个foreach可以解析一层(维)数据

数组方法

 var arr1 = Array(2,4,7,5,8,9,12,13)
    var arr2 = Array(
      Array(3,4,7,92,6),Array(2,54,7,4,12),Array(2,4,67,23,1)
    )
    var arr3 = Array(
      Array(
        Array("henry","male",27),Array("jack","male",21),Array("pola","femal",18)
      ),
      Array(
        Array("make","male",32),Array("yuanfang","female",14),Array("mengya","male",22)
      )
    )
    var arr4 = Array(
      Array(("henry",12),("jack",22)))
    var arr5 = Array(("henry",12),("jack",22))

    //遍历
    println("\n--------------------------1维数组遍历--------------------------")
    arr1.foreach(a=>print(a+"\t"))
    println("\n---------------------------2维数组遍历-------------------------")
    arr2.foreach(x=>{x.foreach(a=>print(a+"\t"))
          print("\t\t|\t\t")
    })
    println("\n---------------------------3维数组遍历------------------------------")
    arr3.foreach(x=>{
      println("\n---1维---")
      x.foreach(y=>{
        println("\n---2维---")
        y.foreach(z=>{
          print(z+"\t")
        })
      })
    })

    println("\n-------------------------------修改数组里面的值---------------------------")
    arr1.foreach(a=>print(a+"\t"))
    arr1.update(2,38)
    println()
    arr1.foreach(a=>print(a+"\t"))
    println("\n-------------------------------函数的定义及赋值传递---------------------------")
    val func = () => {
      println("我爱你")
    }
    val a = func
    a()
    println("\n-------------------------------函数参数写函数 可带入不同函数 实现不同的方法---------------------------")
    val fun1 = (a:String) => println("的方法1带参数:"+a)
    val fun2 = (a:String) => println("的方法2带参数:"+a)
    val fun3 = (a:String=>Unit,b:String)=>{
      a(b)
    }
    fun3(fun1,"我爱你")
    fun3(fun2,"我爱你")
    println("\n-------------------------------map是变形而不是改变原数组的值---------------------------")
    arr1.foreach(a => print(a+"\t"))
    println()
    arr1.map(_+2).foreach(a=>print(a+"\t"))
    println("\n-------------------------------二维数组的map变形:在{x} x后面添加map函数---------------------------")
    arr2.foreach(x=>{x.foreach(a=>print(a+"\t"))
      print("\t\t|\t\t")
    })
    println()
    arr2.foreach(x=>{x.map(_+2).foreach(a=>print(a+"\t"))
      print("\t\t|\t\t")
    })
    println("\n------reduce将相邻的两个数加起来最后得到的所有数的和:怎么实现的呢?------------")
    arr1.foreach(x=>print(x+"\t"))
    println()
    println("-----------------------reduce(_+_)")
    print(arr1.reduce(_ + _)+"\t")
    println()
    println("---------------------看看过程: 这里我有些不理解 第一次取的是2个数组值 而接下来的都是前面的结果+后面的数组值")
    val add= (x:Int,y:Int)=>{
      print(s"${x}+${y}=${x+y}  \t")
      x+y
    }
    print(arr1.reduce(add))

    println("\n-------------------------------柯里化---------------------------")
    def cal(f:(Int,Int)=>Int)(a:Int,b:Int)={
      f(a,b)
    }
    println(cal(_+_)(1,2))
    println("\n-----------------/: arr1.foldLeft(2)(cal5) 其中2是初值 从左向右执行cal5函数-----在cal5中初值2是被减数----------------------")
    arr1.foreach(x=>print(x+"\t"))
    println()
    val cal5=(a:Int,b:Int)=>{
      print(s"${a}-${b}=${a-b}  \t")
      a-b
    }
    println(arr1.foldLeft(2)(cal5))
    println("\n------------------\\:arr1.foldRight(0)(cal5) 0是初值从右往左执行cal5函数---在cal5中初值0是减数------------------------")
    print(arr1.foldRight(0)(cal5))

    println("\n-------------------------------map reduce---------------------------")
    println("先定义一个map 一个reduce方法")
    arr1.foreach(x=>print(x+"\t"))
    println()
    val map = (a:Int,b:Int)=>{
      print(s"map:${a}+${b}=${a+b}  \t")
      a+b
    }
    val reduce = (a:Int,b:Int)=>{
      print(s"reduce:${a}+${b}=${a+b}  \t")
      a+b
    }
    println(arr1.par.aggregate(1)(map,reduce))
    println("\n-------------------------------partition分区----分区是根据属性+判断条件---分成了_1 和 _2 .几个部分--------------------")
    arr1.foreach(x=>print(x+"\t"))
    println()
    val t2 = arr1.partition(_ % 2 == 0)
    t2._1.foreach(x=>print(x+"\t"))
    println("===")
    t2._2.foreach(x=>print(x+"\t"))
    println("\n-------------------------------sliding(3) 分组只有一个参数默认步幅是1---------------------------")
    arr1.foreach(x=>print(x+"\t"))
    println()
    arr1.sliding(3).foreach(x=>{
      x.foreach(y=>print(y+"\t"))
      print("\t|\t")
    })
    println()
    println("---------sliding(2,2)")
    arr1.sliding(2,2).foreach(x=>{
      x.foreach(y=>print(y+"\t"))
      print("\t|\t")
    })
    println("\n-------------------------------二维数组grouped(2)是将数组两两合并---------------------------")
    arr2.foreach(x=> {x.foreach(y=>print(y+"\t"))
      print("\t|\t")
    })
    println()
    arr2.grouped(2)foreach(x=>{x.foreach(y=>y.foreach(z=>print(z+"\t")))
      println()
    })
    println("\n-------------------------------sum---------------------------")
    println(arr1.sum)
    println("\n-------------------------------sount()---------------------------")
    println(arr1.count(_%2==1))
    println("\n-------------------------------max  min---------------------------")
    println(arr1.min)
    println(arr1.max)
    println("\n-------------------------------minBy maxBy---------------------------")
    arr4.foreach(x => println(x.minBy(_._2)))
    println(arr5.minBy(_._2))
    println("------------------clone是复制一个全新的数组出来-----------")
    val arrclone = arr1.clone()
    println(arrclone==arr1)
    println(arrclone.equals(arr1))
    arrclone.foreach(println)

    println("------------------take从左边去   takeright从右边取 ")
    arr1.take(2).foreach(println)
    arr1.takeWhile(_%2==1).foreach(println)

    println("--------提取所有集合中不满足条件的元素---------")
    arr1.filterNot(_%2==1).foreach(println)

    println("--------------to各种  转换类型  要满足条件------")
    println("两个元素的正好符合map键值 map通常用Tuple2去完成")
    val map1 = arr5.toMap
    map1.foreach(println)
 var arr = Array(1,4,11,8,7)
    val arr1 = Array(1,2,3,4)
    val arr2 = Array(4,5,6,7)

    println()
    println("-----------  ++  --------------------")
    val arr3 = arr1 ++ arr2
    arr3.foreach(x=>print(x+"\t"))
    println()
    println("-------------------------------")
    /* 并集 后面的元素类型决定了结果的类型
    下面这段在idea中不能运行   得在 虚拟机scala中运行
    val arr4 = ArrayBuffer(4,5,6)
    arr5 = arr1 ++: arr4
    arr5.foreach(println)
*/

    println()
    println("-----------intersect---交集-----------------")
    //交集
    val arr5 = arr1.intersect(arr2)
    arr5.foreach(x=>print(x+"\t"))

    println()
    println("----------diff--差集----前者相对于后者的差集---------------")
    val arr6 = arr2.diff(arr1)
    arr6.foreach(x=>print(x+"\t"))

    println()
    println("-------------+: 在前面添加元素---不改变原数组---------------")
    val arr7 = 1 +: arr1
    arr7.foreach(x=>print(x+"\t"))

    println()
    println("------------:+  在后面添加元素----不改变原数组---------------")
    val arr8 = arr1 :+ 5
    arr8.foreach(x=>print(x+"\t"))

    println()
    println("-----------addString(builder[,\",\"]) 把数组元素内容连上--适用于多集合拼接------------------")
    val builder = new StringBuilder

    val  str: StringBuilder = arr1.addString(builder)
    print(str)
    println()
    val str1:StringBuilder = arr1.addString(builder,",")
    print(str1)
    println()
    builder.clear()
    val arr9 = arr1.addString(builder, "{", ",", "}")
    print(arr9)



    println()
    println("------arr1.mkString-----适用于单集合拼接--------------------")
    println(arr1.mkString)
    println(arr1.mkString(","))
    println(arr1.mkString("{", ",", "}"))

    println()
    println("---------andThen   函数 = 函数1 andThen 函数2 -----compose是从右向左计算   - 在函数中用 val  xx=(参数)=>{} ----------------")
    val f1 = (x:Int)=>x+2
    val f2 = (x:Int)=>x*2
    val f3 = f1 andThen f2
    println(f3(1))

    val f4 = (x:Int)=>x-2
    val f5 = f1 andThen f2 andThen f4
    println(f5(1))

    val f6 = f1 compose f2 compose f4
    println(f6(1))

    println()
    println("-------arr1.applyOrElse-----下标存在返回下标下的值  不过下标不存在返回这个下标-------------------")
    println(arr1.applyOrElse(1, (ix: Int) => ix))

    println()
    println("-------array   clone    deep    iterator    to...这些都是将集合转换成另一个集合------------------------")
    val arr10 :Array[Int]= arr1.array
    println(arr10 == arr1)
    println(arr10.equals(arr1))
    println(arr10 != arr1)
    println(arr10 ne arr1)       //ne 是:notEquals
    println("------")
    val arr11:Array[Int] = arr1.clone()
    println(arr11 == arr1)
    println(arr11.equals(arr1))
    println(arr11 != arr1)
    println(arr11 ne arr1)       //ne 是:notEquals
    println("---clone 和 deep的返回值是不一样的---")
    val arr12:IndexedSeq[Any] = arr1.deep
    println(arr12 == arr1)
    println(arr12.equals(arr1))
    println(arr12 != arr1)
    println(arr12 ne arr1)       //ne 是:notEquals
    println()
    println("-------------arr.toMap     操作map------------------")
    val arr13:Array[(String,String)] = Array(("henry", "e3234"), ("pola", "2lkhds843"), ("jack", "2klds0934"))
    val map:Map[String,String] = arr13.toMap
    map.keys.foreach(println)
    map.values.foreach(println)
    println(map.contains("pola"))
    println(map.apply("pola"))

    val pair = Map(1->"henry",2->"pola",3->"jack")
    pair.foreach(x=>{
      println(s"${x._1}->${x._2}")
    })

    pair.map(x=>(x._1,x._2+"_01")).foreach(x=>{
      println(s"${x._1}->${x._2}")
    })
    println()
    println("----------arr.to    arr.toBuffer-数组变buffter--------------------")
    val arr14: immutable.IndexedSeq[Int] = arr1.to
    arr14.foreach(println)
    println("-----")
    val buffer: mutable.Buffer[Int] = arr1.toBuffer
    buffer.foreach(println)
    buffer.append(11)
    buffer.foreach(println)

    println()
    println("---转化为不重复值集合------arr.toSet--去重--------arr.distinct-去重-----------")
    arr1.toSet.foreach(println)
    println("---")
    arr1.distinct.foreach(println)

    println()
    println("-----arr.toIterable可迭代的    arr.toIterator只迭代一次------获取集合的地点起对象:-----------------------")
    val ita: Iterable[Int] = arr1.toIterable
    ita.foreach(println)
    println("---")
    ita.foreach(println)
    println("---")
    val ita2: Iterator[Int] = arr1.toIterator
    ita2.foreach(println)
    println("---")
    ita2.foreach(println)

    println()
    println("---------Some--Option=>Some(value) | None--------------------")
    val opt2: Option[String] = None
    val opt1: Option[String] = Some("henrry")
    //流:懒加载模式,针对部分数据处理首选
    val stream1: Stream[Nothing] = Array().toStream
    //println(stream1.head)       //报异常
    println(stream1.headOption)   //None
    println(if (stream1.headOption.isEmpty) "NONE" else stream1.head)   //None

    println()
    println("---------arr.toStream 流---------------------")
    val stream: Stream[Int] = arr1.toStream
    stream.foreach(println)

    println()
    println("----------arr.toVector------不常用 也没明白---------------")
    val vector: Vector[Int] = arr1.toVector
    vector.foreach(println)

    println()
    println("---------arr.canEqual--意义不大--------------------")
    println(arr1.canEqual(Array()))
    println(arr1.canEqual(Map()))

    println()
    println("----偏函数:面向集合中部分元素------arr.collect(筛选函数)----这里要区分 take  takewhile   fill-----------------")
    //提取集合中符合条件的元素 类似于filter
    val pf:PartialFunction[Int,Int] = (x:Int) => x match {
      case x if(x%2==1) => x
    }
    arr1.collect(pf).foreach(println)
    //简化方式
    println("===")
    arr1.collect({case x if(x%2==1)=>x}).foreach(println)
    println("===")
    //提取集合中第一个符合条件的元素:返回:option
    println(arr1.collectFirst({ case x if (x % 2 == 1) => x }))

    println()
    println("------------arr.combinations----排列组合 成一个维数组 ---------------")
    arr1.combinations(3).foreach(x=>println(x.mkString(",")))
    println("-----")
    arr1.permutations.foreach(x=>println(x.mkString(",")))

    println()
    println("------arr.contains-------------------------")
    println(arr1.contains(4))                     //集合中是否包含参数元素
    println(arr1.containsSlice(Array(4, 3)))      //是否完整的包含某个子序列
    println(arr1.exists((p: Int) => p % 2 == 0))  //是否存在符合条件  (至少一个)
    println(arr1.forall((p: Int) => p % 2 == 0))  //集合的元素是否全部符合条件
    println(arr1.sameElements(Array(3, 4)))       //两个集合中是否包含相同的元素,且顺序一致

    println()
    println("-----------arr.find--------arr.filter------------------")
    arr1.filter(_>3)foreach(println)    //找寻所有符合条件的元素(返回多个 并且可重复)
    println("----")
    arr1.find(_>3).foreach(println)     //找到第一个条件的元素(仅仅返回一个)

    println()
    println("------------arr.hasDefiniteSize-有指定大小-----流没有指定的大小-----------------")
    println(arr1.hasDefiniteSize)
    println(arr1.toBuffer.hasDefiniteSize)
    println(arr1.toStream.hasDefiniteSize)

    println()
    println("---------arr.head-arr.last--arr.headOption--arr.lastOption-----------------")
    println(arr1.head)
    println(arr1.last)
    println(arr1.headOption)
    println(arr1.lastOption)

    //println(Array().head)  //报错
    println(Array().headOption)
    println(Array().lastOption)

    println()
    println("----------arr.indexOf---arr.indexOfSlince------------------")
    println(arr1.indexOf(4))                    //获取集合中下标值
    println(arr1.indexOfSlice(Array(3, 4)))     //获取小集合的起始索引位置
    println(arr1.indexWhere(_ < 3))             //获取第一个符合条件的索引下标
    println(arr1.lastIndexOf(2))                //以下从右向左执行
    println(arr1.lastIndexOf(Array(2, 3)))
    println(arr1.lastIndexWhere(_ > 2))

    println()
    println("-----------arr.indices-返回数组下标序列-------------------")
    arr1.indices.foreach(println)
    println()
    println("-----------arr.init-返回除了最后一个元素意外的所有元素---arr.inits----------------")
    val arr15: Array[Int] = arr1.init
    arr15.foreach(println)
    arr1.inits.foreach(line=>println(line.mkString(",")))

    arr1.tail.foreach(println)
    arr1.tails.foreach(line=>println(line.mkString(",")))

    println()
    println("-------------------------------")
    Random.nextInt()
    val buf = ArrayBuffer       //引用
    println(buf)
    val buf1:ArrayBuffer[Int] = ArrayBuffer()    //对象
    println(buf1)
    for(i<-1 to 12){
      buf1.append(1+Random.nextInt(100))
    }
    println("------")
    buf1.foreach(println)
    println("-----")
    buf1.toArray.inits.toArray[Array[Int]].reverse.drop(1).map(x=>x.sum/x.size).foreach(println)


    println()
    println("---------------arr.drop左删   arr.right右删   arr.dropwhile 删条件----------------")
    arr1.drop(2).foreach(println)
    println("----")
    arr1.dropRight(2).foreach(println)
    println("-----")
    arr1.dropWhile(_>3).foreach(println)    //从第一个满足条件的开始 删除满足条件的元素  如果第一个就不满足 那么一个也不删除直接停止
    println()
    println("-----------arr.reverse  倒叙--------------------")
    arr1.reverse.foreach(println)

    println()
    println("-------------arr.startsWith--arr.endsWith----------------")
    println(arr1.startsWith(Array(1, 2)))
    println(arr1.endsWith(Array(3, 4)))
    println()
    println("-----------------arr.isDefinedAt -下标是否在范围内-是否存在参数的下标------------")
    println(arr1.isDefinedAt(6))
    println()
    println("------------arr.isEmpty----是否为空-arr.nonEmpty是否为非空--isTraversable 是否可重复遍历------------")
    println(Array().isEmpty)
    println(arr1.isTraversableAgain)
    println(arr1.iterator.isTraversableAgain)
    println(Array().nonEmpty)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值