How to make method return the same generic as the input?

前端 未结 3 1038
面向向阳花
面向向阳花 2021-02-07 10:20

I want to split a string delimited by commas and use the result as either a Seq or a Set:

def splitByComma(commaDelimited: String): Arr         


        
3条回答
  •  长发绾君心
    2021-02-07 11:01

    There's a method in Scala called to which can transform arbitrary collection to another as long as there is typeclass called CanBuildFrom in scope.

    import scala.collection.generic.CanBuildFrom
    import scala.languageFeature.higherKinds
    
    def genericSplitByComma[S[_]](s: String)(implicit cbf: CanBuildFrom[Nothing, String, S[String]]): S[String] = {
        s.split(",").to[S]
    }
    
    genericSplitByComma[Set]("Hello, hello") //Set(Hello,  hello)
    genericSplitByComma[List]("Hello, hello") //List(Hello,  hello)
    genericSplitByComma[Array]("Hello, hello") //Array(hello, world!)
    

    We don't need to constrain S[_] because this function won't compile if there is no suitable CanBuildFrom in scope. For example, this will fail:

    genericSplitByComma[Option]("Hello, hello")
    

    Below will also fail because our type constructor S[_] accepts only one type argument and the map expects two:

    genericSplitByComma[Map]("Hello, hello")
    

    As Luis Miguel Mejía Suárez and Dmytro Mitin noticed, there was major refactor in collections in just-released Scala 2.13, so it will work up to Scala 2.12.

提交回复
热议问题