Scala backend-kehitykseen ja funktionaaliseen ohjelmointiin · Oppitunti

Opaakit tyypit

Nollakustannuksiset abstraktiot.

Oppitunti 3/413 vaihetta

Opaakit tyypit on ilmainen Scala backend-kehitykseen ja funktionaaliseen ohjelmointiin-oppitunti CoddyKitissä. Tämä on oppitunti 3/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu Scala backend-kehitykseen ja funktionaaliseen ohjelmointiin-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Scala backend-kehitykseen ja funktionaaliseen ohjelmointiin-kurssilla on yhteensä 4 oppituntia.

Mitä opaque-tyypit ovat?

Opaque-tyypit ovat Scala 3:n ominaisuus, jolla luodaan nollakustanteisia abstraktioita. Ne muodostavat käännösaikana erillisen tyypin, mutta kääntyvät suoritusajalla pohjalla olevaksi tyypiksi ilman käärettä.

  • Kääreluokan tarjoama tyyppiturvallisuus.
  • Ei allokoinnin aiheuttamaa lisäkustannusta.
object Distances:
  opaque type Meters = Double

object Main:
  def main(args: Array[String]): Unit =
    println("Opaque types compile to their underlying type")

Opaque-tyypin määrittäminen

Määritä opaque-tyyppi objektin tai luokan sisällä. Kyseisen näkyvyysalueen ulkopuolella Meters- ja Double-tyyppejä käsitellään eri tyyppeinä.

object Distances:
  opaque type Meters = Double
  def meters(d: Double): Meters = d
  def toDouble(m: Meters): Double = m

object Main:
  def main(args: Array[String]): Unit =
    val d = Distances.meters(5.0)
    println(Distances.toDouble(d))

Opaque-tyypin näkyvyysraja

Määrittelyalueen sisällä opaque-tyyppi ja sen pohjalla oleva tyyppi ovat keskenään vaihdettavia. Ulkopuolella näkyvissä on vain opaque-tyyppi, joten raakaa Double-arvoa ei voi vahingossa välittää kohtaan, jossa vaaditaan Meters-arvoa.

object Distances:
  opaque type Meters = Double
  def apply(d: Double): Meters = d
  def show(m: Meters): String = s"$m m"

object Main:
  def main(args: Array[String]): Unit =
    val m = Distances(10.0)
    println(Distances.show(m))

Laajennusmetodien lisääminen

Voit antaa opaque-tyypeille toimintaa määrittelemällä samassa näkyvyysalueessa extension-metodeja. Kutsujat saavat käyttöönsä kätevät operaatiot ilman, että pohjalla oleva tyyppi paljastuu.

object Distances:
  opaque type Meters = Double
  def apply(d: Double): Meters = d
  extension (m: Meters)
    def +(other: Meters): Meters = m + other
    def value: Double = m

object Main:
  def main(args: Array[String]): Unit =
    val total = Distances(3.0) + Distances(4.0)
    println(total.value)

Sekaannusten estäminen

Suurin hyöty on, että kaksi saman pohjalla olevan tyypin päälle määriteltyä opaque-tyyppiä ovat yhteensopimattomia. Metrejä ei voi sekoittaa kilometreihin, vaikka molemmat ovat Double-arvoja.

object Units:
  opaque type Meters = Double
  opaque type Kilometers = Double
  def m(d: Double): Meters = d
  def km(d: Double): Kilometers = d
  def toMeters(k: Kilometers): Meters = k * 1000

object Main:
  def main(args: Array[String]): Unit =
    val far = Units.km(2.0)
    println(Units.toMeters(far))

Rajoitetut opaque-tyypit

Voit antaa opaque-tyypille ylärajan merkinnällä <:. Tällöin osa julkisesta rajapinnasta paljastuu, mutta tarkka esitysmuoto pysyy piilossa.

object Ids:
  opaque type UserId <: Int = Int
  def apply(i: Int): UserId = i

object Main:
  def main(args: Array[String]): Unit =
    val id = Ids(99)
    println(id + 1)

Älykäs rakentaminen validoinnin avulla

Yhdistä opaakit tyypit validoivaan tehdasmetodiin varmistaaksesi, että arvot ovat aina sallittuja. Konstruktori pysyy yksityisenä; vain validoitu tehdasmetodi on julkinen.

object Ages:
  opaque type Age = Int
  def of(i: Int): Option[Age] =
    if i >= 0 && i < 150 then Some(i) else None
  extension (a: Age) def value: Int = a

object Main:
  def main(args: Array[String]): Unit =
    println(Ages.of(30).map(_.value))
    println(Ages.of(-1))

Suorituksen aikaiset kustannukset puuttuvat

Toisin kuin value class- tai case class -kääre, opaakki tyyppi ei luo yhtään oliota suorituksen aikana. JVM:ssä Meter-arvojen List on kirjaimellisesti double-arvojen lista, joten boxingia ei tapahdu.

object Temps:
  opaque type Celsius = Double
  def c(d: Double): Celsius = d
  extension (t: Celsius) def value: Double = t

object Main:
  def main(args: Array[String]): Unit =
    val readings = List(Temps.c(20.0), Temps.c(21.5))
    println(readings.map(_.value).sum)

Opaakki tyyppi ja tyyppialias

Tavallinen type X = Y -alias on läpinäkyvä: X ja Y ovat kaikkialla täysin keskenään vaihdettavissa. Opaakki tyyppi piilottaa tämän yhtäsuuruuden oman näkyvyysalueensa ulkopuolella ja tarjoaa siten todellisen tyyppiturvallisuuden.

object Demo:
  type Name = String          // transparent alias
  opaque type Email = String  // opaque
  def email(s: String): Email = s
  extension (e: Email) def raw: String = e

object Main:
  def main(args: Array[String]): Unit =
    val e = Demo.email("a@b.com")
    println(e.raw)

Opaakki tyyppi ja case class -kääre

case class Meters(value: Double) -kääreen kaltainen case class lisää myös tyyppiturvallisuutta, mutta varaa olion. Opaakit tyypit tarjoavat saman turvallisuuden pohjatyypin suorituskyvyllä.

object Money:
  opaque type Cents = Long
  def cents(n: Long): Cents = n
  extension (c: Cents)
    def +(o: Cents): Cents = c + o
    def value: Long = c

object Main:
  def main(args: Array[String]): Unit =
    val total = Money.cents(150) + Money.cents(50)
    println(total.value)

Milloin opaakkeja tyyppejä käytetään

Käyttäkää opaakkeja tyyppejä, kun haluatte vahvan toimialatason tyypityksen suorituskyvyn kannalta kriittisissä kohdissa tai suurissa kokoelmissa.

  • Erottakaa suureet toisistaan (Meters ja Seconds).
  • Pakottakaa validoidut invariantit.
  • Välttäkää kääreiden aiheuttamat allokointikustannukset.
object Geo:
  opaque type Latitude = Double
  def lat(d: Double): Option[Latitude] =
    if d >= -90 && d <= 90 then Some(d) else None
  extension (l: Latitude) def value: Double = l

object Main:
  def main(args: Array[String]): Unit =
    println(Geo.lat(41.0).map(_.value))

Pikatarkistus

Testatkaa ymmärrystänne opaakeista tyypeistä.

Kertaus

Opitte Scala 3:n opaakit tyypit.

  • opaque type X = Y piilottaa yhtäsuuruuden näkyvyysalueensa ulkopuolella.
  • Tarjotkaa API:a varten tehdasmetodeja ja extension-metodeja.
  • Eri opaakit tyypit, joilla on sama pohjatyyppi, eivät ole yhteensopivia.
  • Valinnaiset ylärajat merkinnällä <: paljastavat osan API:sta.
  • Suorituksen aikaiset kustannukset ovat nolla, toisin kuin case class -kääreillä.
object Ids:
  opaque type OrderId = String
  def apply(s: String): OrderId = s
  extension (o: OrderId) def raw: String = o

object Main:
  def main(args: Array[String]): Unit =
    val id = Ids("ORD-1")
    println(id.raw)
Aloita maksutta

Opi Scala tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
39
Oppitunnit
143

Usein kysytyt kysymykset

Onko oppitunti ”Opaakit tyypit” ilmainen?

Kyllä – oppitunnin ”Opaakit tyypit” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko Scala backend-kehitykseen ja funktionaaliseen ohjelmointiin-kurssin, päivitä CoddyKit PROhon. Scala backend-kehitykseen ja funktionaaliseen ohjelmointiin-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”Opaakit tyypit”?

Nollakustannuksiset abstraktiot. Harjoittelet Scala backend-kehitykseen ja funktionaaliseen ohjelmointiin-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni Scala backend-kehitykseen ja funktionaaliseen ohjelmointiin-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin Scala backend-kehitykseen ja funktionaaliseen ohjelmointiin-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 3/4.

Kuinka kauan ”Opaakit tyypit”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä Scala backend-kehitykseen ja funktionaaliseen ohjelmointiin-oppitunnilla?

Kyllä. Jokainen Scala backend-kehitykseen ja funktionaaliseen ohjelmointiin-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. Merkityksellinen sisennys
  2. Enumit Scalassa 3
  3. Opaakit tyypit
  4. Yhdiste- ja leikkaustyypit
← Takaisin: Scala backend-kehitykseen ja funktionaaliseen ohjelmointiin