04.11.2011

Скала за бежанците на Java Част 1: основни (String [])

Original on http://www.codecommit.com/blog/scala/scala-for-java-refugees-part-1

7 Jan
2008

Вие знаете кой сте. Вие сте разработчик, който вдигна Java години, може би като втори език и по-добра алтернатива на C++, може би първата си език в индустрията. Чувствате се комфортно с Java, знаете тънкостите, неговите настроения. Това е като стара приятелка, не могат да се чувстват вече настроението, но знаете как точно да го търка, така че се усмихва. С една дума, вие сте майстора, и Java е вашият кон инструмент.

Започваме да макар и да стане малко по-прагматично за избор на език., Меко казано, Java меден месец свърши. Макар едва ли можете да намерите достатъчно вина с език само пеша, вие със сигурност достатъчно отворен за разглеждане на алтернативи. Вие сте чували за тази нова fangled нещо, наречено Руби – как може да не са чули, имайки предвид нивото на шума, произвеждан от нейните последователи. Вие сте впечатлен от краткостта на изгражда и силата на неговите синтаксис, но вие не се продават на идеята за използване скриптов език, за да изгради своя App предприятието. Dynamic пишете и TextMate всички са добре и добри, но за реалния свят железен кон, ти започваш да се нуждаят от нещо с малко повече гръбнак. Като добър прагматик, се придържате с инструмент, който работи: Java.

Добрата новина е, че има светлина в края на тунела. Има нов език на сцената, която е разработчик света от буря. Скала изглежда да предложи всичко, което сте били търсите на език: пишете статичен, компилират до байткод (така че да можете да я изпълните на всички онези древни Java-съвместими сървъри), сбит и изразителен синтаксис. Вие сте виждали няколко примера, които наистина са привлекли вниманието ви. Той изглежда автентично копие на Java, освен с половин безполезен изгражда изхвърлен. Не точка и запетая, няма публичен статично невалидни квалификации метод, той дори изглежда да има някакъв вид на статични механизъм тип извод.

Единственият проблем сега е разберете от къде да започнете. Сте опитали да търсите на интернет страницата на Scala, но това, което сте намерили сте спрели в песните си. Всичко е така… функционални. Lamdas, ред функции, неизменно състояние, рекурсия, на wazoo. Изведнъж нещата изглеждат по-малко обещаващ.

Не се страхувайте, вие бежанец на Java EE решетка на желязо, не всичко е загубено. Вярно е, че Скала е функционален език, но също така е императив и обектно-ориентирано. Какво означава това? Това означава, че вие не трябва да пишат код, с единствената цел на приятен Haskell Къри. Можете да напишете кода, който всъщност може да прочетете една седмица от сега. Може дори да бъде в състояние да покаже този код на Java-нежен колеги и те просто може да я разбере. Вие не трябва да къри всяка функция и да се избегне на всяка цена петелки. Можете да напишете своето Java приложения в Скала. Ти просто се нуждаят от въвеждането на правото.

Представяне

Ако сте като мен и може да се идентифицира с по-горе, тогава тази серия е за вас. Чел съм много статии и ръководства за Scala (серия Алекс Blewitt е силно препоръчително, особено ако сте заинтересувани от по-функционална страна на живота), но няколко от тези уроци са опитали да направим нещата по-лесни за движение на мелница Java разработчик, за да направите прехода. Аз лично имам много малко FP (Функционално програмиране) опит, така че аз не мисля, че бих могъл да напиша статия за пренасяне Схема код, за да Scala, дори и ако исках да. Вместо това, тази серия ще се фокусира върху това, как Scala е точно като Java, с изключение на по- добре.

Споменах ли, Алекс Scala серия въвеждането? Сериозно, това е голямо четене, а не лошо въвеждане в Скала и на себе си. След като сте готови да си чета ramblings, трябва да прегази и прочетете някои от по-последователен неща. Колкото по-весело!

Първи стъпки

object HelloWorld extends Application {
  println("Hello, World!")
}

Нищо подобно, все неща, подвижен с малко код. Забележете освежаваща липса на задължителни точка и запетая. Ние можем да ги използват така или иначе, но те ​​не са необходими, освен ако имаме нужда от няколко изявления на един ред. Този код проба прави точно това, изглежда, го определя заявление (когато тичам с помощта на Скала преводач) ще отпечата “Hello, World!” към стандартния изход. Ако поставите този код във файл с разширение .scala, можете да го компилирате с помощта на scalac компилатор. Резултатът ще бъде един клас файл. Може да се технически работи .class, с помощта на Java преводач, но вие ще трябва да се забъркваш с CLASSPATH малко. Най-лесният нещо, което трябва да направите, е просто използвайте скала команда, като така:

scalac hello.scala
scala HelloWorld

Обърнете внимание на името на файла в въпрос? За разлика от Java, Scala не ви принуждава да се определят всички обществени класи индивидуално във файлове със същото име. Scala всъщност ви позволява да определят най-много класове, както искате за файл (мисля C++ или Ruby). Тя все още е добра практика да се следват Java именуване конвенция, обаче, така че са добри програмисти, ние ще спасим нашата HelloWorld например в един файл, наречен “HelloWorld.scala “.

Редактори

Само на кратка бележка за първите няколко минути с Скала: използването на правото редактор е от ключово значение. Както трябва да са научили от много години в света на Java, ИДЕС са ваш приятел. Скала, е много по-млади език все още не е много добра подкрепа IDE. Това е статично, общ език цел, като Java, така че IDE подкрепа ще се случи. За момента, обаче, сте остана с много ограничен набор от опции.

  • Eclipse (с помощта на един от двата калпав и нестабилна Scala плъгини)
  • Emacs
  • IntelliJ (основно само синтаксис Отбелязването подкрепа)
  • TextMate
  • VIM
  • jEdit

Има няколко други възможности, които съществуват, но те ​​са biggies (за да видите пълния списък, погледнете в Разни/Скала-инструмент за подпомагане на/директорията, под инсталационната корен Scala). Моята лична препоръка е, че вие използвате jEdit или TextMate, макар че, ако сте чувство приключенски, сте свободни да опитате една от плъгини Eclipse. Scala подкрепа в Eclipse има предимство (поне с бета плъгин) на функции, като семантични осветяване, код на завършване на сградата (на Scala, така и вносни Java класове) и други IDE черти. В моя опит, макар че, както Eclipse плъгини нестабилна точка на негодни за употреба и като такъв, не си струва труда. Scala е език много по-чисти от Java, така че наистина има по-малко нужда от супер мощен IDE. Би било хубаво, не става въпрос за това, но не е задължително.

По-Hello World

object HelloWorld2 {
  def main(args:Array[String]) = {
    var greeting = ""
    for (i <- 0 until args.length) {
      greeting+= (args(i)+ " ")
    }
    if (args.length > 0) greeting = greeting.substring(0, greeting.length - 1)
    println(greeting)
  }
}

Запишете в нов файл (ние ще наречем “HelloWorld2.scala”), събира и работи с помощта на следните команди:

scalac HelloWorld2.scala
scala HelloWorld2 Hello, World!

Отново, това отпечатва “Hello, World!” Към стандартния изход. Този път ние направихме нещата малко по-различно, макар и. Сега имаме аргументи за командния ред, които идват в нашите App. Ние дефинираме променлива от тип String, обхождане на масив и след това да се нарече малко на низове. Сравнително лесно, но определено по-сложна, отколкото първия пример. (Забележка: Scala mavens не се съмнява предложи на използването на масива # deepMkString (низ) (подобно на Ruby, Array:: присъединят към метод), вместо да iterating над масива Това е правилният подход, но исках да илюстрирам малко повече от на езика, отколкото само една неясна функция API).

Първото нещо, което трябва да се отбележи в този пример е, че ние всъщност дефинира основен метод. В първия пример, ние просто удължен Прилагане и обявява всичко по подразбиране конструктор. Това е хубаво и по-кратка, но тя има два проблема. Първо, ние не може да направи разбор на командния ред ARGS по този начин. На второ място, като примери са изключително объркващо за новаците на Scala, тъй като тя изглежда повече от леко магически. Не се притеснявайте, аз ще обясня магията зад първия ни пример във времето, но за сега само на вярата.

В примера, ние определяме Основният метод, който изглежда нещо като нашия стар приятел Java, публично статично невалидни основни. В действителност, това е почти точно Scala аналог на точно този метод подпис в Java. С оглед на това, опитен разработчик ще бъде в състояние да вземем няколко неща за езика само с проверка.

Първо, тя изглежда като всички методи са имплицитно обществени. Това е донякъде вярно. Scala методи са публични по подразбиране, което означава, че не е публично модификатор метод (частни и защитени както са определени). Той също така изглежда Scala методи са статични по подразбиране. Това обаче, не е съвсем правилно.

Scala не може да кажем, статиката. Колкото по-скоро да се признае, че толкова по-лесно езика ще бъде за вас. Вместо това, той има специален синтаксис, който ви позволява лесно да се определи и използването Сингълтън класове (това е какво обект). Това, което наистина сме обявени за Сингълтън клас с метода инстанция, основни аз ще разгледаме по-подробно по-късно, но за сега просто мисля за обекта като клас само с статични членове.

След задълбочена проверка на нашата извадка, ние получаваме малко на вникване в двете масив синтаксис Scala, както и представа за това как човек може изрично да укажете различни видове. Конкретно, нека се съсредоточим върху линията за деклариране на метод.

def main(args:Array[String]) = {

В този случай, ARGS е метод параметър от тип масив [String]. Това е да се каже, ARGS е низ масив. В Scala, Array е всъщност клас (истинска класа, а не като масиви Java), което отнема тип параметър, определящ вида на неговите елементи. Еквивалентни синтаксис на Java (ако приемем, Java Array клас) ще бъде нещо като това:

public static void main(Array<String> args) {

В Scala, променлив тип се задава посредством променливата: Тип синтаксис. Така, ако искам да декларирам променлива, която е изрично от тип Int, ще бъде направено като това:

var myInteger:Int

Ако се вгледате в пробата, ние всъщност не декларират променлива от тип String. Въпреки това, ние не изрично да укажете всякакъв вид. Това е така, защото ние сме се възползват от механизъм Скала тип извод. Тези две твърдения са semanticly еквивалентни:

var greeting = ""

var greeting:String = ""

В първата декларация, това е очевидно за нас, че поздрав е String, като по този начин компилаторът е в състояние да го направи извод за нас. И двете поздрав сек staticly тип проверени, вторият е само на 7 знака по-кратък.:-)

Наблюдателни програмисти също така ще забележите, че ние не са декларирали връщания тип за нашите Основният метод. Това е, защото Scala може да се направи извод за нас, както и. Ако наистина искаше да каже нещо изрично, бихме могли да декларират неща като това:

def main(args:Array[String]):Unit = {

Още веднъж, тип antecedes елемент, разделени от двоеточие. Като настрана, звено е типът на Scala за I-наистина – не грижи-какво-I-връщане ситуации. Мислете за него като на Java обекти и невалидни видове, които се сливат в една.

Iterating Над масив

var greeting = ""
for (i <- 0 until args.length) {
  greeting+= (args(i)+ " ")
}

Между другото, това е да се отбележи в този критичен момент, че Конвенцията за вдлъбнатината на Scala е в действителност две места, вместо да се разделите или четири пространство конвенция, която е толкова често срещано явление в Java. Отстъп не е значително, така че наистина може да направи неща, обаче искате, но другите четири милиарда деветстотин деветдесет и девет милиона деветстотин деветдесет и девет хиляди деветстотин деветдесет и девет души в света използват два космически конвенция, така че може би си струва като свикнете с него. Логиката зад конвенция е, че дълбоко вложени структура не е лош знак в Скала като тя е в Java, като по този начин на вдлъбнатината може да бъде по-коварен.

Тази извадка от код е малко по-малко интуитивно очевидно, отколкото тези, които сме изпитали предварително. Ние започваме от обявяване на променлива, поздрав от изведе тип String трудности там. Втората линия е с рядко виждани Скала за контур, малко повече от видовете извод, метод позоваването на “примитивните” буквално и Стара инстанция. Разработчици с Ruby опит вероятно ще признаят този еквивалент синтаксис:

for i in 0..(args.size - 1)
  greeting+= args[i]+ " "
end

Трудността на Scala за контур е Стара инстанция, създадена в RichInt #, докато метод. Ние може да се счупят този синтаксис на отделни отчети, като така:

val range = 0.until(args.length)
for (i <- range) {

О, това не е правописна грешка там обявява посредством поредица Вал вместо Var. Използването на Вал, ние сме обявяване на променлива гама като константа (в смисъл на Java, а не като C/C+ + Const). Мислете за него като по-кратка форма на Java окончателно модификатор.

Скала дава възможност да се позове на методи, които използват няколко различни синтаксиса. В този случай, ние сме свидетели на стойност methodName параметри синтаксис, който е буквално еквивалент на value.methodName (параметри) синтаксис. Друго важно действие, което е като място тук е имплицитно преобразуване на Int буквално (0) инстанция на scala.runtime.RichInt. Как това отнема място не е важно точно сега, само че RichInt всъщност класа за обявяване до метод, който връща инстанция на обхват.

След като имаме нашата гама съд (независимо от това как е създаден), ние преминаваме стойност в магията за синтаксис. В декларация за контур, ние сме определяне на нова променлива и на заключи тип Int. Тази променлива съдържа текущата стойност, докато вървим през диапазона [0, args.length), включително долната граница, но не горната.

Накратко, за даден контур е почти, но не съвсем равностойни на следните малко на Java:

for (int i = 0; i < args.length; i++) {

Очевидно синтаксиса на Java е ясно определяне на обхвата тестове, вместо да използвате някаква Стара обект, но въпросът остава. За щастие, почти никога не трябва да използвате този синтаксис контур в Scala, както ще видим след малко.

Тялото на цикъла е един последен малко интересна код в нашия пример. Очевидно ние сме добавяне на стойност към нашия поздрав String. Това, което аз съм сигурен, удари, вие смешно (Знам, че ме е), е фактът, че масив достъп на Scala се извършва със скоби, а не квадратни скоби. Предполагам, че това прави някакъв смисъл, тъй като Scala тип параметри са уточнени, като се използват квадратни скоби (вместо символи greater-than/less-than), но тя все още изглежда малко странно.

За да обобщим, горната част на проба в Скала е логично, равностойни на по-ниска проба в Java:

var greeting = ""
for (i <- 0 until args.length) {
  greeting+= (args(i)+ " ")
}

String greeting = "";
for (int i = 0; i < args.length; i++) {
    greeting+= args[i]+ ” “;
}

По-добър начин за обхождане

В Java 5, видяхме въвеждането на така наречените/синтаксис всеки Iterator. Така, в Java можем да направим нещо подобно:

for (String arg: args) {
    greeting+= arg+ " ";
}

Много по-кратки. Scala има подобен синтаксис, определени като високо-ред функция - функция, която заема друга функция като параметър. Ще се докоснете по тези по-късно, но за момента можете да го вземете като по-магически прах fairie:

args.foreach { arg =>
  greeting+= (arg+ " ")
}

Тук ние виждаме, че foreach е метод на класа Array, че отнема затваряне (анонимна функция) като параметър. Foreach метод после вика, че затварянето веднъж за всеки елемент, който минава елемент като параметър за затваряне (ARG). В ARG параметър изведе тип String, защото ние сме iterating над масив от низове.

Сега, както видяхме по-рано, Scala методи може да се нарече по различен начин. В този случай ние се обаждате foreach без скоби за по- голяма яснота. Ние също може да са написани примерните като този:

args.foreach(arg => {
  greeting+= (arg+ " ")
})

Scala всъщност определя още по -кратък начин да определят един ред затваряне. Ние можем да пропуснете фигурните скоби изцяло чрез преместване на инструкцията в метод позоваването:

args.foreach(arg => greeting+= (arg+ " "))

Не е зле! Така че нашата напълно пренаписана проба изглежда така:

object HelloWorld2 {
  def main(args:Array[String]) = {
    var greeting = ""
    args.foreach(arg => greeting+= (arg+ " "))
    if (args.length > 0) greeting = greeting.substring(0, greeting.length - 1)
    println(greeting)
  }
}

Синтаксисът изглежда страхотно, но какво е всъщност прави? Аз не знам за вас, но аз мразя се налага да използвате приложения, които аз не знам как да се възпроизведе. С малко работа, ние можем да пресъздаде същината на Scala foreach метод в чист Java. Да приемем за момент, че Java е Array клас. В този клас Array, нека да се преструвам, имаше foreach метод, който взе една единствена инстанция, като параметър., Определени от код, тя може да изглежда така:

public interface Callback<T> {
    public void operate(T element);
}
public class Array<T> {
    //...
    public void foreach(Callback<T> callback) {
        for (T e: contents) {   // our data structure is called "contents"
            callback.operate(e);
        }
    }
}

Можех да определи foreach рекурсивно (както е определено в Scala), но не забравяйте, аз се стараем да поддържаме тези обяснения, които са ясни на заплетените блато, че е FP.:-)

Придържайки се с целта ни да го видите в аналогова към Scala foreach, ето как бихме използвали по-горе API в Java:

public class HelloWorld2 {
    public static void main(Array<String> args) {
        final StringBuilder greeting = new StringBuilder();
        args.foreach(new Callback<String>() {
            public void operate(String element) {
                greeting.append(element).append(' ');
            }
        });
        if (args.length() > 0) {
            greeting.setLength(greeting.length() - 1);
        }
        System.out.println(greeting.toString());
    }
}

Започваме да виждаме, защо Scala е законно обжалване? Ако сте като мен, просто искате Scala да бъде по-кратък Java. В този случай, това е точно това, което имаме. Не странно функционални cruft, неизменни нито една държава не. Само твърди, трудолюбиви код.

Няколко думи за вградената Видове

Тъй като Scala е построен на JVM, той наследява много от нейните основни API директно от Java. Това означава, че можете да взаимодействате с Java APIs. Повече от това, това означава, че кодът, който Вие пишете в Скала използва Java APIs и функции. Например, нашата извадка HelloWorld2 използва низ променлива поздрав.. Тази променлива е буквално на типа java.lang.String. Когато Вие декларирате, целочислена променлива (тип Int) компилатора конвертира Java примитивен тип Int.

Това е също да се отбележи, че има редица вградени в имплицитни конверсии (точно като на Int да RichInt видяхме по- рано със създаването Стара). Например, Scala Array [String] ще бъде по подразбиране конвертира до Java String [], когато премина на метод, който приема такива стойности. Дори Скала тип параметри са достъпни и съвместими с Java генеричните лекарства (в текущата версия на развитието на Scala и плоча за включване в 2.6.2). Накратко, когато използвате Scala сте наистина използват Java, само с различен синтаксис.

Заключение

Scala не трябва да бъде сложна, ненужно академични или изискват магистърска степен по информатика. Скала може да бъде език за обикновения човек, 9-5 разработчик, който работи по интернет, че през следващата корпоративни приложения. Той има реален потенциал да се осигури ясен синтаксис, Java никога не е без да преставаме силата и стабилността на доверие, първокласни език. Убедени?

До следващия, класове, методи и свойства: всичко, което трябва да знаете, за да се търкаля с обектно-ориентирано програмиране в Скала.

Comments are closed.