Biorąc pod uwagę niedawne ogłoszenie przez Google oficjalnej pomocy technicznej dotyczącej rozwoju Androida przez Kotlin , pomyślałem, że nadejdzie czas, aby sondować społeczność w poszukiwaniu niesamowitych wskazówek golfowych dla tego stosunkowo nowego języka JVM.
Kotlin zawiera unikalne połączenie funkcji wśród rodzeństwa JVM, co czyni go potencjalnie atrakcyjnym dla golfistów:
- przeciążenie operatora
- funkcje rozszerzenia lokalnego , infix i statycznego
- inteligentne obsady
- Konstruktorzy typu groovy
- pseudonimy
- zakresy
- bogaty pakiet funkcjonalnych kolekcji
- obsługa skryptów
Jak więc wycisnąć ostatnie bajty z mojego programu Kotlin? Poproszę jedną wskazówkę na odpowiedź.
Odpowiedzi:
Funkcje rozszerzeń
Funkcje rozszerzeń mogą naprawdę pomóc w zmniejszeniu nazw metod wbudowanych i ich łańcuchów, przykładem może być:
fun String.c() = this.split("").groupingBy{it}.eachCount()
ale pomaga to tylko wtedy, gdy:
A) Połączenie jest wystarczająco długie, aby anulować definicję
B) Połączenie zostanie powtórzone
Zastosowanie lambdas zamiast metod
Lambda może powrócić bez użycia słowa kluczowego return, oszczędzając bajty
KotlinGolfer
Projekt, który rozpocząłem tutaj, który pobiera ładny kod Kotlin i automatycznie podaje posty z testami i linkami TIO
źródło
Użyj
+
zamiasttoString
Jak można się spodziewać,
String
przeciąża+
operatora do konkatenacji łańcuchów, podobnie jak to.Jednak sprawdzenie dokumentów mówi nam, że akceptuje
Any?
, nie tylkoString
. Jak wspomniano:Innymi słowy,
String + anything
upewnij się, że zadzwoniłeś.toString()
po prawej stronie przed połączeniem. To pozwala nam skrócićit.toString()
do""+it
ogromnych oszczędności 8 bajtów w najlepszym wypadku i 6 bajtów w najgorszym.Użyj
fold
zamiastjoinToString
W związku z powyższym, jeśli dzwonisz,
map
a następniejoinToString
możesz to skrócić, używającfold
zamiast tego.źródło
Począwszy od wersji 1.3 możesz całkowicie pomijać argumenty w fun main () , goląc w ten sposób 18 znaków (czyli długość
args:Array<String>
).źródło
Definiowanie Int w params
Prawdopodobnie będzie to miało kilka specyficznych przypadków użycia, w których może być tego warte, ale w ostatnim pytaniu, w którym grałem w golfa, stwierdziłem, że mogę zaoszczędzić kilka bajtów, definiując moją zmienną jako parametry opcjonalne zamiast definiować je w funkcji.
Przykład z mojej odpowiedzi na to pytanie:
definiowanie zmiennej w funkcji:
fun String.j()={var b=count{'-'==it}/2;var a=count{'/'==it};listOf(count{'o'==it}-a,a-b,b)}
definiowanie zmiennych jako params:
fun String.j(b:Int=count{'-'==it}/2,a:Int=count{'/'==it})=listOf(count{'o'==it}-a,a-b,b)
ponieważ
var a=
ma taką samą długość, ponieważa:Int=
zdefiniowanie ich będzie miało taką samą liczbę bajtów (tak jest tylko w przypadkuInt
), ale ponieważ teraz mam tylko 1 linię w funkcji, mogę ją upuścić{}
i upuszczam też jeden;
(drugi to zastąpiony przez a,
)Więc jeśli są jakieś funkcje, które wymagają zdefiniowania Int, i byłby 1 linijką, jeśli nie zdefiniowałeś int w funkcji - wtedy wykonanie tego jako parametru pozwoli zaoszczędzić kilka bajtów
źródło
Funkcja
to
infixDostępna jest standardowa funkcja poprawki,
to
która tworzyPair
s dwóch wartości. Jest powszechnie używanymapOf()
do definiowaniaMap
s, ale potencjalnie może być znacznie krótszy niżPair()
konstruktor.źródło
Destrukcja w argumentach lambda
Powiedz, że chcesz zaakceptować
Pair<*,*>
lambda. Zwykle radzenie sobie z tym byłoby denerwujące. Na przykład, oto lambda, która pobiera aPair
i sprawdza, czy dwie wartości są równe:To jest rozwlekłe i niezdarne. Na szczęście, Kotlin pozwala destructure wszelkiego rodzaju destructable (dowolny typ, który implementuje
componentN()
metody, takie jakPair
,Triple
itd.) Jako argumenty lambda. Możemy to przepisać w następujący sposób:Wygląda podobnie do wzorca pasującego krotkę w czymś takim jak F # iw wielu przypadkach jest. Ale szeroka gama typów w Kotlinie wspiera destrukcję (
MatchResult
jest przydatna).Możesz wziąć więcej argumentów. Powiedz, że twoja lambda musiała przyjąć
Pair
dodatkową wartość. Po prostu napiszesz podpis lambda w ten sposób:źródło