当前位置: 首页>>代码示例>>Scala>>正文


Scala tailrec类代码示例

本文整理汇总了Scala中scala.annotation.tailrec的典型用法代码示例。如果您正苦于以下问题:Scala tailrec类的具体用法?Scala tailrec怎么用?Scala tailrec使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。


在下文中一共展示了tailrec类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Scala代码示例。

示例1: trainDecay

//设置package包名称以及导入依赖的类
package com.esri

import breeze.linalg.Vector
import org.apache.commons.math3.util.FastMath

import scala.annotation.tailrec
import scala.math._


  def trainDecay(trainVec: Seq[Vector[Double]],
                 epochMax: Int,
                 alphaDecay: Decay,
                 radiusDecay: Decay
                )(implicit pb: ProgressBar = NoopProgressBar()): Unit = {

    val trainLen = trainVec.length
    val rnd = new java.security.SecureRandom()

    @tailrec
    def _train(epoch: Int): Unit = {
      if (epoch < epochMax) {
        val alpha = alphaDecay(epoch)
        val rad = radiusDecay(epoch)
        val vec = trainVec(rnd.nextInt(trainLen))
        train(vec, alpha, rad)
        pb.progress()
        _train(epoch + 1)
      }
    }

    _train(0)

    pb.finish()
  }
} 
开发者ID:mraad,项目名称:spark-som-path,代码行数:36,代码来源:SOM.scala

示例2: Server

//设置package包名称以及导入依赖的类
package sh.webserver

import java.net.ServerSocket
import java.util.concurrent.{ExecutorService, Executors}

import sh.webserver.request.Request

import scala.annotation.tailrec

class Server(port: Int) {
  def start() {
    val server = new ServerSocket(port)
    val pool = Executors.newFixedThreadPool(8)
    listen(server, pool)
  }

  @tailrec
  private def listen(server : ServerSocket,pool : ExecutorService) {
    val socket = server.accept()
    pool.execute(new RequestHandler(socket))
    listen(server, pool)
  }
} 
开发者ID:stefan-hering,项目名称:scalaserver,代码行数:24,代码来源:Server.scala

示例3: ProblemFiftyEight

//设置package包名称以及导入依赖的类
package org.nason.euler.fifty

import scala.annotation.tailrec

import org.nason.euler.EulerUtils
import org.nason.euler.NumberUtils

object ProblemFiftyEight {
  def main(args: Array[String])
  {
    EulerUtils timing { println( solution ) }
  }
  
  def solution =
  {
    def ne( n:Long ) = n*n - 3*n + 3
    def sw( n:Long ) = n*n - n + 1
    def nw( n:Long ) = n*n - 2*n + 2
    def allThree( n:Long ) = List( ne(n), sw(n), nw(n) )
    def PrimeFrac = 0.1
    @tailrec def count( i:Long, nDiag:Long, nPrime:Long ) : Long =
    {
      if ( i>3 && nPrime.toDouble/nDiag.toDouble < PrimeFrac )
        i-2
      else
      {
        val nDiag2 = nDiag + 4
        val nPrime2 = nPrime + allThree(i).filter(NumberUtils.fastPrimeLong).length
        count( i+2, nDiag2, nPrime2 )
      }
    }
    count( 3, 1, 0 )
  }
} 
开发者ID:drkeoni,项目名称:euler-jms-scala,代码行数:35,代码来源:ProblemFiftyEight.scala

示例4: TorrentPiece

//设置package包名称以及导入依赖的类
package com.karasiq.bittorrent.format

import akka.util.ByteString

import scala.annotation.tailrec
import scala.collection.mutable.ArrayBuffer

case class TorrentPiece(index: Int, size: Int, sha1: ByteString, file: TorrentFile)
case class TorrentPieceBlock(piece: TorrentPiece, offset: Int, size: Int)

object TorrentPiece {
  def pieces(files: TorrentFiles): IndexedSeq[TorrentPiece] = {
    // Total torrent size
    val totalSize = files.files.map(_.size).sum

    @tailrec
    def pieceSequenceRec(buffer: ArrayBuffer[TorrentPiece], offset: Long, fileOffset: Long, pieceIndex: Int, fileSeq: Seq[TorrentFile]): IndexedSeq[TorrentPiece] = fileSeq match {
      case Seq(currentFile, fs @ _*) if fs.nonEmpty && fileOffset >= currentFile.size ?
        pieceSequenceRec(buffer, offset, 0L, pieceIndex, fs)

      case fs @ Seq(currentFile, _*) if offset < totalSize ?
        val length = Array(files.pieceLength.toLong, totalSize - offset).min
        require(length <= Int.MaxValue)
        val sha1 = files.pieces.slice(pieceIndex * 20, (pieceIndex * 20) + 20)
        val piece = TorrentPiece(buffer.length, length.toInt, sha1, currentFile)
        pieceSequenceRec(buffer :+ piece, offset + length, fileOffset + length, pieceIndex + 1, fs)

      case other ?
        buffer.result()
    }
    pieceSequenceRec(new ArrayBuffer[TorrentPiece](files.pieces.length / 20), 0L, 0L, 0, files.files)
  }

  def blocks(piece: TorrentPiece, sizeLimit: Int): IndexedSeq[TorrentPieceBlock] = {
    @tailrec
    def pieceBlockRec(buffer: ArrayBuffer[TorrentPieceBlock], offset: Int): IndexedSeq[TorrentPieceBlock] = {
      if (offset >= piece.size) {
        buffer.result()
      } else {
        val block = TorrentPieceBlock(piece, offset, Array(sizeLimit, piece.size - offset).min)
        pieceBlockRec(buffer :+ block, offset + block.size)
      }
    }
    pieceBlockRec(new ArrayBuffer[TorrentPieceBlock](piece.size / sizeLimit + 1), 0)
  }
} 
开发者ID:Karasiq,项目名称:torrentstream,代码行数:47,代码来源:TorrentPiece.scala

示例5: Collections

//设置package包名称以及导入依赖的类
package akka.util

import scala.collection.immutable
import scala.annotation.tailrec


private[akka] object Collections {

  case object EmptyImmutableSeq extends immutable.Seq[Nothing] {
    override final def iterator = Iterator.empty
    override final def apply(idx: Int): Nothing = throw new java.lang.IndexOutOfBoundsException(idx.toString)
    override final def length: Int = 0
  }

  abstract class PartialImmutableValuesIterable[From, To] extends immutable.Iterable[To] {
    def isDefinedAt(from: From): Boolean
    def apply(from: From): To
    def valuesIterator: Iterator[From]
    final def iterator: Iterator[To] = {
      val superIterator = valuesIterator
      new Iterator[To] {
        private[this] var _next: To = _
        private[this] var _hasNext = false

        @tailrec override final def hasNext: Boolean =
          if (!_hasNext && superIterator.hasNext) { // If we need and are able to look for the next value
            val potentiallyNext = superIterator.next()
            if (isDefinedAt(potentiallyNext)) {
              _next = apply(potentiallyNext)
              _hasNext = true
              true
            } else hasNext //Attempt to find the next
          } else _hasNext // Return if we found one

        override final def next(): To =
          if (hasNext) {
            val ret = _next
            _next = null.asInstanceOf[To] // Mark as consumed (nice to the GC, don't leak the last returned value)
            _hasNext = false // Mark as consumed (we need to look for the next value)
            ret
          } else throw new java.util.NoSuchElementException("next")
      }
    }

    override lazy val size: Int = iterator.size
    override def foreach[C](f: To ? C) = iterator foreach f
  }

} 
开发者ID:love1314sea,项目名称:akka-2.3.16,代码行数:50,代码来源:Collections.scala

示例6: apply

//设置package包名称以及导入依赖的类
package com.oradian.autofuture

import scala.annotation.tailrec

trait AutoFuture {
  def apply(source: String): AutoFuture.Result
}

object AutoFuture {
  val tasks = List[AutoFuture](
    ProcedureSyntaxConversion
  , AdaptTupleArgumentsExplicitly
  )

  sealed trait Result
  object Result {
    case class Error(error: String) extends Result
    case class Success(body: String) extends Result
    case object Noop extends Result
  }

  def apply(source: String): Result =
    process(source, tasks, Result.Noop)

  @tailrec
  private[autofuture] def process(source: String, tasks: List[AutoFuture], last: Result): Result = {
    tasks match {
      case Nil =>
        last

      case head :: tail =>
        head(source) match {
          case error: Result.Error =>
            error

          case newLast @ Result.Success(source) =>
            process(source, tail, newLast)

          case Result.Noop =>
            process(source, tail, last)
        }
    }
  }
} 
开发者ID:oradian,项目名称:sbt-auto-future,代码行数:45,代码来源:AutoFuture.scala

示例7: Newton

//设置package包名称以及导入依赖的类
package cz.letal.progfun.toying

import scala.annotation.tailrec

object Newton extends App {

  def sqrt(value: Double, precision: Double = 1E-6): Double = {

    def isPreciseEnough(x: Double): Boolean = Math.abs((x * x - value) / value) < precision

    def newtonStep(x: Double): Double = {
      val functionValue = x * x - value
      val gradient = 2 * x

      x - functionValue / gradient
    }

    @tailrec
    def sqrtIter(xPrev: Double): Double = {
      val xNext = newtonStep(xPrev)

      if (isPreciseEnough(xNext))
        xNext
      else
        sqrtIter(xNext)
    }

    sqrtIter(value)
  }

  println(s"${Math.sqrt(2)} - Math.sqrt")
  println("----------------------------------")
  for (a <- 1 to 15) {
    println(s"${sqrt(2, Math.pow(10, -a))} - precision $a significant digits")
  }
} 
开发者ID:letalvoj,项目名称:progfun_assignments,代码行数:37,代码来源:Newton.scala

示例8: RemoteMultiMap

//设置package包名称以及导入依赖的类
package com.init6.channels.utils

import scala.annotation.tailrec
import scala.collection.mutable


object RemoteMultiMap {
  def apply[A, B]() = new RemoteMultiMap[A, B]
}

sealed class RemoteMultiMap[A, B] extends mutable.HashMap[A, mutable.Set[B]] with mutable.MultiMap[A, B] {

  def +=(kv: (A, B)): this.type = addBinding(kv._1, kv._2)
  def +=(key: A): this.type = {
    if (!contains(key)) {
      +=(key -> mutable.Set[B]())
    } else {
      this
    }
  }

  def ++=(kv: (A, Iterable[B])): this.type = {
    @tailrec
    def loop(kv: (A, Iterable[B])): Unit = {
      if (nonEmpty) {
        +=(kv._1 -> kv._2.head)
        loop(kv._1 -> kv._2.tail)
      }
    }
    loop(kv)
    this
  }

  def -=(kv: (A, B)): this.type = {
    get(kv._1).foreach(_ -= kv._2)
    this
  }
} 
开发者ID:fjaros,项目名称:init6,代码行数:39,代码来源:RemoteMultiMap.scala

示例9: Collections

//设置package包名称以及导入依赖的类
package akka.util

import scala.collection.immutable
import scala.annotation.tailrec


private[akka] object Collections {

  case object EmptyImmutableSeq extends immutable.Seq[Nothing] {
    override final def iterator = Iterator.empty
    override final def apply(idx: Int): Nothing = throw new java.lang.IndexOutOfBoundsException(idx.toString)
    override final def length: Int = 0
  }

  abstract class PartialImmutableValuesIterable[From, To] extends immutable.Iterable[To] {
    def isDefinedAt(from: From): Boolean
    def apply(from: From): To
    def valuesIterator: Iterator[From]
    final def iterator: Iterator[To] = {
      val superIterator = valuesIterator
      new Iterator[To] {
        private[this] var _next: To = _
        private[this] var _hasNext = false

        @tailrec override final def hasNext: Boolean =
          if (!_hasNext && superIterator.hasNext) { // If we need and are able to look for the next value
          val potentiallyNext = superIterator.next()
            if (isDefinedAt(potentiallyNext)) {
              _next = apply(potentiallyNext)
              _hasNext = true
              true
            } else hasNext //Attempt to find the next
          } else _hasNext // Return if we found one

        override final def next(): To =
          if (hasNext) {
            val ret = _next
            _next = null.asInstanceOf[To] // Mark as consumed (nice to the GC, don't leak the last returned value)
            _hasNext = false // Mark as consumed (we need to look for the next value)
            ret
          } else throw new java.util.NoSuchElementException("next")
      }
    }

    override lazy val size: Int = iterator.size
    override def foreach[C](f: To ? C) = iterator foreach f
  }

} 
开发者ID:Starofall,项目名称:Chakka,代码行数:50,代码来源:Collections.scala

示例10: escape

//设置package包名称以及导入依赖的类
package shared

import scala.annotation.tailrec



  def escape(msg:String):String = {
    @tailrec
    def go(msg:List[Char], acc:String):String = msg match {
      case '&' :: xs => go(xs, acc + "&amp;")
      case '>' :: xs => go(xs, acc + "&gt;")
      case '<' :: xs => go(xs, acc + "&lt;")
      case   x :: xs => go(xs, acc + x)
      case       Nil => acc
    }
    go(msg.toList, "")
  }
} 
开发者ID:Starofall,项目名称:Chakka,代码行数:19,代码来源:Utils.scala

示例11: ScalaDeque

//设置package包名称以及导入依赖的类
package com.naoh.beef.internal

import java.util

import scala.annotation.tailrec

class ScalaDeque[T] private(val inner: util.ArrayDeque[T]) extends AnyVal {
  @inline
  def isEmpty: Boolean = inner.isEmpty

  @inline
  def add(a: T): Boolean = inner.add(a)

  @inline
  def <<(a: T): Boolean = inner.add(a)

  @inline
  def polls[U](f: (T) => U): Unit = pollTraverse(f)

  @inline
  def size: Int = inner.size()

  @inline
  def pollOr[U](f: T => U)(or: => Unit): Unit = {
    poll.map(f).getOrElse(or)
  }

  @inline
  def poll: Option[T] = Option(inner.poll())

  @tailrec
  private def pollTraverse[U](f: T => U): Unit = {
    poll match {
      case Some(x) =>
        f(x)
        pollTraverse(f)
      case _ =>
    }
  }
}

object ScalaDeque {
  def empty[T] = new ScalaDeque[T](new util.ArrayDeque[T])
} 
开发者ID:naoh87,项目名称:grpc-scala-experiment,代码行数:45,代码来源:ScalaDeque.scala

示例12: ByteStringToDeltaStage

//设置package包名称以及导入依赖的类
package com.martinseeler.dtf.stages

import akka.stream.stage.{GraphStage, GraphStageLogic, InHandler, OutHandler}
import akka.stream.{Attributes, FlowShape, Inlet, Outlet}
import akka.util.ByteString
import com.martinseeler.dtf.{FactorizedDeltaTick, NonNegativeFactorizedDeltaTick}
import scodec.Attempt.{Failure, Successful}
import scodec.DecodeResult
import scodec.bits.BitVector

import scala.annotation.tailrec

class ByteStringToDeltaStage extends GraphStage[FlowShape[ByteString, FactorizedDeltaTick]] {

  val in = Inlet[ByteString]("ByteStringToDeltaStage.in")
  val out = Outlet[FactorizedDeltaTick]("ByteStringToDeltaStage.out")

  def shape: FlowShape[ByteString, FactorizedDeltaTick] = FlowShape(in, out)

  def createLogic(inheritedAttributes: Attributes): GraphStageLogic =
    new GraphStageLogic(shape) with OutHandler {

      def onPull(): Unit = if (!hasBeenPulled(in)) tryPull(in)
      setHandler(out, this)

      val inHandler = new InHandler {

        def decodeAllFromBits(bits: BitVector): (Vector[NonNegativeFactorizedDeltaTick], BitVector) = {

          @tailrec
          def compute(results: Vector[NonNegativeFactorizedDeltaTick], remainingBits: BitVector): (Vector[NonNegativeFactorizedDeltaTick], BitVector) = {
            NonNegativeFactorizedDeltaTick.nonNegFactorizedDeltaTickCodecV.decode(remainingBits) match {
              case Successful(DecodeResult(value, BitVector.empty)) =>
                (results :+ value, BitVector.empty)
              case Successful(DecodeResult(value, remainder)) if remainder.sizeGreaterThan(25) =>
                compute(results :+ value, remainder)
              case Successful(DecodeResult(value, remainder)) =>
                (results :+ value, remainder)
              case Failure(e) =>
                println("e = " + e)
                (results, BitVector.empty)
            }
          }

          compute(Vector.empty, bits)
        }

        private[this] var remainingBits = BitVector.empty

        def onPush(): Unit = {
          val bits = BitVector.view(grab(in).asByteBuffer)
          val (results, rest) = decodeAllFromBits(remainingBits ++ bits)
          emitMultiple(out, results.map(_.withNegatives))
          remainingBits = rest
        }
      }

      setHandler(in, inHandler)
    }

} 
开发者ID:MartinSeeler,项目名称:dense-tick-file-format,代码行数:62,代码来源:ByteStringToDeltaStage.scala

示例13: Mult

//设置package包名称以及导入依赖的类
package newts

import cats.kernel.Eq
import cats.syntax.functor._
import cats.{Applicative, Eval, Monad, Monoid, Traverse}

import scala.annotation.tailrec

final case class Mult[A](getMult: A) extends AnyVal

object Mult extends MultInstances0 {
  implicit def newtypeInstance[A]: Newtype.Aux[Mult[A], A] = Newtype.from[Mult[A], A](Mult.apply)(_.getMult)

  implicit val monadInstance: Monad[Mult] = new Monad[Mult] {
    def pure[A](x: A): Mult[A] = Mult(x)
    def flatMap[A, B](fa: Mult[A])(f: A => Mult[B]): Mult[B] = f(fa.getMult)
    @tailrec
    def tailRecM[A, B](a: A)(f: A => Mult[Either[A, B]]): Mult[B] = f(a) match {
      case Mult(Left(a1)) => tailRecM(a1)(f)
      case Mult(Right(b)) => Mult(b)
    }
  }

  implicit def monoidInstance[A](implicit num: Numeric[A]): Monoid[Mult[A]] = new Monoid[Mult[A]] {
    val empty: Mult[A] = Mult(num.one)
    def combine(x: Mult[A], y: Mult[A]): Mult[A] = Mult(num.times(x.getMult, y.getMult))
  }

  implicit def eqInstance[A: Eq]: Eq[Mult[A]] = Eq.by(_.getMult)
}

trait MultInstances0 {
  implicit val traverseInstance: Traverse[Mult] = new Traverse[Mult] {
    def traverse[G[_], A, B](fa: Mult[A])(f: A => G[B])(implicit ev: Applicative[G]): G[Mult[B]] =
      f(fa.getMult).map(Mult(_))

    def foldLeft[A, B](fa: Mult[A], b: B)(f: (B, A) => B): B =
      f(b, fa.getMult)

    def foldRight[A, B](fa: Mult[A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] =
      f(fa.getMult, lb)
  }
} 
开发者ID:julien-truffaut,项目名称:newts,代码行数:44,代码来源:Mult.scala

示例14: Max

//设置package包名称以及导入依赖的类
package newts

import cats.kernel.Order
import cats.syntax.functor._
import cats.syntax.order._
import cats.{Applicative, Eval, Monad, Monoid, Semigroup, Show, Traverse}
import newts.internal.MinBounded

import scala.annotation.tailrec

final case class Max[A](getMax: A) extends AnyVal

object Max extends MaxInstances0{
  implicit def newtypeInstance[A]: Newtype.Aux[Max[A], A] = Newtype.from[Max[A], A](Max.apply)(_.getMax)

  implicit val monadInstance: Monad[Max] = new Monad[Max] {
    def pure[A](x: A): Max[A] = Max(x)
    def flatMap[A, B](fa: Max[A])(f: A => Max[B]): Max[B] = f(fa.getMax)
    @tailrec
    def tailRecM[A, B](a: A)(f: A => Max[Either[A, B]]): Max[B] = f(a) match {
      case Max(Left(a1)) => tailRecM(a1)(f)
      case Max(Right(b)) => Max(b)
    }
  }
  
  implicit def instances[A: Order]: Order[Max[A]] with Semigroup[Max[A]] = new Order[Max[A]] with Semigroup[Max[A]] {
    def combine(x: Max[A], y: Max[A]): Max[A] = Max(x.getMax max y.getMax)
    def compare(x: Max[A], y: Max[A]): Int = x.getMax compare y.getMax
  }

  implicit def showInstance[A](implicit ev: Show[A]): Show[Max[A]] = new Show[Max[A]] {
    override def show(f: Max[A]): String = s"Max(${ev.show(f.getMax)})"
  }
}

trait MaxInstances0{
  implicit def maxMonoid[A](implicit A: MinBounded[A]): Monoid[Max[A]] = new Monoid[Max[A]]{
    def empty: Max[A] = Max(A.minValue)
    def combine(x: Max[A], y: Max[A]): Max[A] = Max(x.getMax max y.getMax)
  }

  implicit val traverseInstance: Traverse[Max] = new Traverse[Max] {
    def traverse[G[_], A, B](fa: Max[A])(f: A => G[B])(implicit ev: Applicative[G]): G[Max[B]] =
      f(fa.getMax).map(Max(_))

    def foldLeft[A, B](fa: Max[A], b: B)(f: (B, A) => B): B =
      f(b, fa.getMax)

    def foldRight[A, B](fa: Max[A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] =
      f(fa.getMax, lb)
  }
} 
开发者ID:julien-truffaut,项目名称:newts,代码行数:53,代码来源:Max.scala

示例15: FirstOption

//设置package包名称以及导入依赖的类
package newts

import cats.{Applicative, Eval, MonadCombine, Monoid, MonoidK, Show, Traverse}
import cats.instances.option._
import cats.syntax.functor._
import cats.syntax.traverse._
import cats.kernel.Eq

import scala.annotation.tailrec

final case class FirstOption[A](getFirstOption: Option[A]) extends AnyVal

object FirstOption extends FirstOptionInstances0 {
  implicit def newtypeInstance[A]: Newtype.Aux[FirstOption[A], Option[A]] =
    Newtype.from[FirstOption[A], Option[A]](FirstOption.apply)(_.getFirstOption)

  implicit val monadCombineInstance: MonadCombine[FirstOption] = new MonadCombine[FirstOption] {
    def empty[A]: FirstOption[A] = FirstOption(None)
    def combineK[A](x: FirstOption[A], y: FirstOption[A]): FirstOption[A] = FirstOption(x.getFirstOption.orElse(y.getFirstOption))
    def pure[A](x: A): FirstOption[A] = FirstOption(Some(x))
    def flatMap[A, B](fa: FirstOption[A])(f: A => FirstOption[B]): FirstOption[B] =
      fa.getFirstOption.fold(empty[B])(f)

    @tailrec
    def tailRecM[A, B](a: A)(f: A => FirstOption[Either[A, B]]): FirstOption[B] =
      f(a).getFirstOption match {
        case None           => empty
        case Some(Left(a1)) => tailRecM(a1)(f)
        case Some(Right(b)) => pure(b)
      }
  }

  implicit def monoidInstance[A]: Monoid[FirstOption[A]] = MonoidK[FirstOption].algebra

  implicit def eqInstance[A: Eq]: Eq[FirstOption[A]] = Eq.by(_.getFirstOption)

  implicit def showInstance[A: Show]: Show[FirstOption[A]] = new Show[FirstOption[A]] {
    override def show(f: FirstOption[A]): String = s"FirstOption(${Show[Option[A]].show(f.getFirstOption)})"
  }
}

trait FirstOptionInstances0 {
  implicit val traverseInstance: Traverse[FirstOption] = new Traverse[FirstOption] {
    def traverse[G[_], A, B](fa: FirstOption[A])(f: A => G[B])(implicit ev: Applicative[G]): G[FirstOption[B]] =
      fa.getFirstOption.traverse(f).map(FirstOption(_))

    def foldLeft[A, B](fa: FirstOption[A], b: B)(f: (B, A) => B): B =
      fa.getFirstOption.fold(b)(f(b, _))

    def foldRight[A, B](fa: FirstOption[A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] =
      fa.getFirstOption.fold(lb)(f(_, lb))
  }
} 
开发者ID:julien-truffaut,项目名称:newts,代码行数:54,代码来源:FirstOption.scala


注:本文中的scala.annotation.tailrec类示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。