」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > Clojure 悖論

Clojure 悖論

發佈於2024-09-02
瀏覽:982

Several years ago, I came across The Python Paradox by Paul Graham. In it, Graham argues that Lisp and Python programmers are often those who genuinely care about programming and, as a result, tend to do it better than, for instance, Java programmers. This perspective fundamentally changed how I viewed Python as a language.

At first, I found Python’s lack of semicolons and reliance on indentation to be strange and uncomfortable. I even saw Python as a tool for building only basic applications. However, with the rise of serverless computing, machine learning, and data science, the immense power of Python has become increasingly apparent. The language is getting faster, and its ecosystem is rapidly growing. Libraries like FastAPI and Pandas are truly remarkable, allowing us to solve problems succinctly.

As programmers, our job is to solve problems, and since we read more code than we write, having fewer lines of code reduces the surface area for bugs to hide and helps us avoid cognitive overload.

When I started working with AWS's Boto3, I realized that tasks that previously took me 30 lines of Java could now be done in just 3 lines of Python. It was mind-blowing. Don’t get me wrong, Java is still one of my favorite programming languages, and with its new release cadence, it’s only getting better. But the amount of ceremony required to accomplish basic tasks in Java is something sometimes we’d all prefer to avoid.

Recently, I've been experimenting with Go. Although it prides itself on simplicity, IMHO I find it too verbose. I know that excellent tools have been built with Go, and there are certain ideas and applications that should be developed with it. Its compilation speed and efficient memory usage make Go a strong contender, it might even be the best combination of developer experience and performance, which is becoming increasingly important in modern, cloud-native applications.

The Clojure Paradox

However, after 10 years in the industry and having deployed applications in several languages, I remain a fan of Clojure. Despite its niche status, Clojure incorporates ideas from other languages, such as Go’s goroutines. It’s a Lisp dialect, inherently immutable, and designed with concurrency in mind. What stands out most to me is how Clojure allows you to focus on solving problems without the burden of unnecessary ceremony. The majority of the code is about the problem itself; it’s data-oriented, and I often find that it helps me enter a Flow state (Happiness) where programming becomes truly enjoyable.

With Go, I currently have mixed feelings. While it brings many good ideas to the table in terms of concurrency and simplicity, I find that the codebases tend to be larger and more ceremonious. Clojure, on the other hand, tends to produce code that is less brittle and primarily composed of pure functions.

Timeless ideas

I’ve always been a fan of timeless ideas because they are often the most important and foundational, yet they are also the most overlooked and I feel that Clojure fully embraces of all them.

  • Programs composed mostly of pure functions are more robust and easier to test.
  • Immutability reduces complexity.
  • Smaller programs have fewer bugs.
  • Software development is fundamentally about composition.
  • We should minimize
  • Incidental complexity can make a system harder to understand, maintain, and extend.

Code examples

In this example, I read a book from an online text file and perform basic processing to illustrate how the same problem can be approached in different programming languages and paradigms.

Go

My opinion: The absence of sets and higher-order functions makes the problem more difficult to solve. Basic tasks, such as filtering, often need to be done in an imperative manner.

package main

import (
    "fmt"
    "io"
    "net/http"
    "regexp"
    "sort"
    "strings"
)

var commonWords = map[string]struct{}{
    "a": {}, "able": {}, "about": {}, "across": {}, "after": {}, "all": {}, "almost": {}, "also": {}, "am": {}, "among": {},
    "an": {}, "and": {}, "any": {}, "are": {}, "as": {}, "at": {}, "be": {}, "because": {}, "been": {}, "but": {}, "by": {},
    "can": {}, "cannot": {}, "could": {}, "dear": {}, "did": {}, "do": {}, "does": {}, "either": {}, "else": {}, "ever": {},
    "every": {}, "for": {}, "from": {}, "get": {}, "got": {}, "had": {}, "has": {}, "have": {}, "he": {}, "her": {}, "hers": {},
    "him": {}, "his": {}, "how": {}, "however": {}, "i": {}, "if": {}, "in": {}, "into": {}, "is": {}, "it": {}, "its": {},
    "just": {}, "least": {}, "let": {}, "like": {}, "likely": {}, "may": {}, "me": {}, "might": {}, "most": {}, "must": {},
    "my": {}, "neither": {}, "no": {}, "nor": {}, "not": {}, "of": {}, "off": {}, "often": {}, "on": {}, "only": {}, "or": {},
    "other": {}, "our": {}, "own": {}, "rather": {}, "said": {}, "says": {}, "she": {}, "should": {}, "since": {}, "so": {},
    "some": {}, "than": {}, "that": {}, "the": {}, "their": {}, "them": {}, "then": {}, "there": {}, "these": {}, "they": {},
    "this": {}, "those": {}, "through": {}, "to": {}, "too": {}, "more": {}, "upon": {}, "us": {}, "wants": {}, "was": {},
    "we": {}, "were": {}, "what": {}, "when": {}, "where": {}, "which": {}, "while": {}, "who": {}, "whom": {}, "why": {},
    "will": {}, "with": {}, "would": {}, "yet": {}, "you": {}, "your": {}, "shall": {}, "before": {}, "now": {}, "one": {},
    "even": {},
}

func getBook() string {
    resp, err := http.Get("https://www.gutenberg.org/cache/epub/84/pg84.txt")
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        panic(err)
    }
    return string(body)
}

func getWords(book string) []string {
    re := regexp.MustCompile(`[\w’] `)
    return re.FindAllString(book, -1)
}

func filterWords(words []string) []string {
    var result []string
    for _, word := range words {
        w := strings.ToLower(word)
        _, ok := commonWords[w]
        if !ok {
            result = append(result, w)
        }
    }
    return result
}

func getFrequentWords(words []string, n int) map[string]int {
    var filteredWords []string
    for _, word := range words {
        _, ok := commonWords[word]
        if !ok {
            filteredWords = append(filteredWords, strings.ToLower(word))
        }
    }
    var unorderedWords = make(map[string]int)
    for _, word := range words {
        unorderedWords[word]  
    }
    type wordFrequency struct {
        word  string
        count int
    }
    var wordFrequencies []wordFrequency
    for word, count := range unorderedWords {
        wordFrequencies = append(wordFrequencies, wordFrequency{word, count})
    }
    sort.Slice(wordFrequencies, func(i, j int) bool {
        return wordFrequencies[i].count > wordFrequencies[j].count
    })

    topN := make(map[string]int)
    for i := 0; i 



Java

My opinion: It does the job. Since Java 8, the language has been getting better. Even though it has some verbosity, you'll find that we now have collectors and functions to perform tasks without issues. The tedious part is having to put everything into classes just to solve a problem.

package jorgetovar.book;

import org.springframework.web.client.RestTemplate;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class Book {

    private static final Set commonWords = Set.of(
            "a", "able", "about", "across", "after", "all", "almost", "also", "am", "among", "an",
            "and", "any", "are", "as", "at", "be", "because", "been", "but", "by", "can", "cannot",
            "could", "dear", "did", "do", "does", "either", "else", "ever", "every", "for", "from",
            "get", "got", "had", "has", "have", "he", "her", "hers", "him", "his", "how", "however",
            "i", "if", "in", "into", "is", "it", "its", "just", "least", "let", "like", "likely",
            "may", "me", "might", "most", "must", "my", "neither", "no", "nor", "not", "of", "off",
            "often", "on", "only", "or", "other", "our", "own", "rather", "said", "says", "she",
            "should", "since", "so", "some", "than", "that", "the", "their", "them", "then",
            "there", "these", "they", "this", "those", "through", "to", "too", "more", "upon",
            "us", "wants", "was", "we", "were", "what", "when", "where", "which", "while", "who",
            "whom", "why", "will", "with", "would", "yet", "you", "your", "shall", "before", "now", "one",
            "even"
    );

    public static String getBook() {
        RestTemplate restTemplate = new RestTemplate();
        String bookUrl = "https://www.gutenberg.org/cache/epub/84/pg84.txt";
        return restTemplate.getForObject(bookUrl, String.class);
    }

    public static List getWords(String book) {
        List words = new ArrayList();
        Pattern wordPattern = Pattern.compile("[\\w’] ");
        Matcher matcher = wordPattern.matcher(book);
        while (matcher.find()) {
            words.add(matcher.group());
        }
        return words;
    }

    public static List> getFrequentWords(List words, int takeN) {
        return words.stream()
                .map(String::toLowerCase)
                .filter(word -> !commonWords.contains(word))
                .collect(Collectors.groupingBy(word -> word, Collectors.counting()))
                .entrySet()
                .stream()
                .sorted((e1, e2) -> Long.compare(e2.getValue(), e1.getValue()))
                .limit(takeN)
                .map(e -> Map.entry(e.getKey(), e.getValue()))
                .toList();
    }

    public static Map> getLongestWords(List words, int takeN) {
        return words.stream()
                .map(String::toLowerCase)
                .distinct()
                .sorted(getLongestWord())
                .limit(takeN)
                .collect(Collectors.groupingBy(String::length));
    }

    public static boolean isPalindrome(String word) {
        return word.contentEquals(new StringBuilder(word).reverse());
    }

    public static List getLongestPalindromes(List words, int takeN) {
        return words.stream()
                .map(String::toLowerCase)
                .filter(word -> !commonWords.contains(word))
                .distinct()
                .filter(Book::isPalindrome)
                .sorted(getLongestWord())
                .limit(takeN)
                .toList();
    }

    private static Comparator getLongestWord() {
        return Comparator.comparingInt(String::length).reversed();
    }

    public static void main(String[] args) {
        String book = getBook();
        List words = getWords(book);
        System.out.println("Total Words: "   words.size());
        System.out.println("Most Frequent Words:");
        getFrequentWords(words, 10).forEach(entry -> System.out.println(entry.getKey()   ": "   entry.getValue()));

        System.out.println("\nLongest Words Grouped by Length:");
        getLongestWords(words, 10).forEach((length, group) -> System.out.println("Length "   length   ": "   group));

        System.out.println("\nLongest Palindromes:");
        getLongestPalindromes(words, 3).forEach(System.out::println);
    }


}

Kotlin

My opinion: For me, this could be the most fun and robust enterprise language. It has good support for functions and immutability.

package jorgetovar.book

import org.springframework.web.client.RestTemplate


val commonWords = setOf(
    "a", "able", "about", "across", "after", "all", "almost", "also", "am", "among", "an",
    "and", "any", "are", "as", "at", "be", "because", "been", "but", "by", "can", "cannot",
    "could", "dear", "did", "do", "does", "either", "else", "ever", "every", "for", "from",
    "get", "got", "had", "has", "have", "he", "her", "hers", "him", "his", "how", "however",
    "i", "if", "in", "into", "is", "it", "its", "just", "least", "let", "like", "likely",
    "may", "me", "might", "most", "must", "my", "neither", "no", "nor", "not", "of", "off",
    "often", "on", "only", "or", "other", "our", "own", "rather", "said", "says", "she",
    "should", "since", "so", "some", "than", "that", "the", "their", "them", "then",
    "there", "these", "they", "this", "those", "through", "to", "too", "more", "upon",
    "us", "wants", "was", "we", "were", "what", "when", "where", "which", "while", "who",
    "whom", "why", "will", "with", "would", "yet", "you", "your", "shall", "before", "now", "one",
    "even"
)

fun getBook(): String {
    val restTemplate = RestTemplate()
    val bookUrl = "https://www.gutenberg.org/cache/epub/84/pg84.txt"
    return restTemplate.getForObject(bookUrl, String::class.java) ?: ""
}

fun getWords(book: String): List {
    return "[\\w’] ".toRegex().findAll(book).map { it.value }.toList()
}

fun getFrequentWords(words: List, takeN: Int): List> {
    val filteredWords = words
        .map { it.lowercase() }
        .filter { it !in commonWords }

    return filteredWords
        .groupingBy { it }
        .eachCount()
        .toList()
        .sortedByDescending { it.second }
        .take(takeN)

}

fun getLongestWords(words: List, takeN: Int): Map> {
    val uniqueWords = words
        .map { it.lowercase() }
        .distinct()
    return uniqueWords
        .sortedByDescending { it.length }
        .take(takeN)
        .groupBy { it.length }
}

fun isPalindrome(word: String): Boolean {
    return word == word.reversed()
}

fun getLongestPalindromes(words: List, takeN: Int): List {
    val uniqueWords = words
        .map { it.lowercase() }
        .filter { it !in commonWords }
        .distinct()
    val palindromes = uniqueWords
        .filter { isPalindrome(it) }
    return palindromes
        .sortedByDescending { it.length }.take(takeN)
}


fun main() {
    val book = getBook()
    val words = getWords(book)
    println("Total Words: ${words.size}")
    println("Most Frequent Words:")
    println(getFrequentWords(words, 10))
    println("Longest Words Grouped by Length:")
    println(getLongestWords(words, 5))
    println("Longest Palindromes:")
    println(getLongestPalindromes(words, 3))
}

Python

My opinion: I really like using this language. Sometimes it can get messy because it's too permissive and allows you to mutate variables, etc. But in general, you'll find that list comprehensions are really good for solving these kinds of problems. I don’t like the result when using classes, but for this example, it was just enough.

import requests
import re

from collections import Counter, defaultdict


def get_book():
    book = requests.get("https://www.gutenberg.org/cache/epub/84/pg84.txt")
    return book.text


def get_words(book):
    return re.findall(r"[a-zA-Z0-9’] ", book)


common_words = {
    "a", "able", "about", "across", "after", "all", "almost", "also", "am", "among", "an",
    "and", "any", "are", "as", "at", "be", "because", "been", "but", "by", "can", "cannot",
    "could", "dear", "did", "do", "does", "either", "else", "ever", "every", "for", "from",
    "get", "got", "had", "has", "have", "he", "her", "hers", "him", "his", "how", "however",
    "i", "if", "in", "into", "is", "it", "its", "just", "least", "let", "like", "likely",
    "may", "me", "might", "most", "must", "my", "neither", "no", "nor", "not", "of", "off",
    "often", "on", "only", "or", "other", "our", "own", "rather", "said", "says", "she",
    "should", "since", "so", "some", "than", "that", "the", "their", "them", "then",
    "there", "these", "they", "this", "those", "through", "to", "too", "more", "upon",
    "us", "wants", "was", "we", "were", "what", "when", "where", "which", "while", "who",
    "whom", "why", "will", "with", "would", "yet", "you", "your", "shall", "before", "now", "one",
    "even"
}


def get_frequent_words(words, take_n):
    frequent_words = [word.lower() for word in words if word.lower() not in common_words]
    word_frequencies = Counter(frequent_words)
    return word_frequencies.most_common(take_n)


def get_longest_words(words, take_n):
    unique_words = set(word.lower() for word in words)
    longest_groups = defaultdict(list)
    sorted_works = sorted(unique_words, key=len, reverse=True)[:take_n]
    for word in sorted_works:
        longest_groups[len(word)].append(word)
    return dict(longest_groups)


def is_palindrome(word):
    return word == word[::-1]


def get_longest_palindromes(words, take_n):
    unique_words = set(word.lower() for word in words if word.lower() not in common_words)
    palindromes = [word for word in unique_words if is_palindrome(word)]
    palindromes.sort(key=len, reverse=True)
    return palindromes[:take_n]


def main():
    book = get_book()
    words = get_words(book)
    print("Total words:", len(words))
    print(get_frequent_words(words, 10))
    print(get_longest_words(words, 10))
    print(get_longest_palindromes(words, 3))


if __name__ == "__main__":
    main()

Clojure

My opinion: The problem with Clojure is its niche nature. It’s usually difficult to understand the basics of the language and its philosophy. The amount of parentheses is unattractive to a lot of people, but in general, I find it the most beautiful implementation.

(ns clojure-book.core
  [:require [clojure.string :as str]]
  (:gen-class))

(def book (slurp "https://www.gutenberg.org/cache/epub/84/pg84.txt"))

(def words (re-seq #"[\w|’] " book))

(def common-words
  #{"a" "able" "about" "across" "after" "all" "almost" "also" "am" "among" "an"
    "and" "any" "are" "as" "at" "be" "because" "been" "but" "by" "can" "cannot"
    "could" "dear" "did" "do" "does" "either" "else" "ever" "every" "for" "from"
    "get" "got" "had" "has" "have" "he" "her" "hers" "him" "his" "how" "however"
    "i" "if" "in" "into" "is" "it" "its" "just" "least" "let" "like" "likely"
    "may" "me" "might" "most" "must" "my" "neither" "no" "nor" "not" "of" "off"
    "often" "on" "only" "or" "other" "our" "own" "rather" "said" "says" "she"
    "should" "since" "so" "some" "than" "that" "the" "their" "them" "then"
    "there" "these" "they" "this" "those" "through" "to" "too" "more" "upon"
    "us" "wants" "was" "we" "were" "what" "when" "where" "which" "while" "who"
    "whom" "why" "will" "with" "would" "yet" "you" "your" "shall" "before" "now" "one"
    "even"
    })

(defn palindrome? [word]
  (= (seq word) (reverse (seq word)))
  )

(defn frequent-words [take-n]
  (->> words
       (map str/lower-case)
       (remove common-words)
       (frequencies)
       (sort-by val)
       (take-last take-n))
  )

(defn longest-words [take-n]
  (->> words
       (map str/lower-case)
       (distinct)
       (sort-by count)
       (take-last take-n)
       (group-by count)
       )
  )

(defn longest-palindromes [take-n]
  (->> words
       (map str/lower-case)
       (distinct)
       (filter palindrome?)
       (sort-by count)
       (take-last take-n)
       )
  )

(defn -main
  [& args]
  (println (str "Total words:" (count words)))
  (println (take 10 words))
  (println (frequent-words 10))
  (println (longest-words 10))
  (println (longest-palindromes 3))

  )

Conclusion

Software is constantly evolving, and client expectations for the programs they use and build are growing. However, our focus should remain on solving problems, eliminating incidental complexity, and taking pride in our craft. There is no 'best' programming language—only tools that help us address specific problems. Even when working with legacy systems, we have the opportunity to make a positive impact through good naming conventions, best practices, improving the architecture, and generally putting the project in a better state

There has never been a better time to be an engineer and create value in society through software.

  • LinkedIn
  • Twitter
  • GitHub

If you enjoyed the articles, visit my blog jorgetovar.dev

版本聲明 本文轉載於:https://dev.to/jorgetovar/the-clojure-paradox-41ke?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • JavaScript 中的 require 與 import
    JavaScript 中的 require 與 import
    我記得當我開始編碼時,我會看到一些js檔案使用require()來匯入模組和其他檔案使用import。這總是讓我感到困惑,因為我並不真正理解其中的差異是什麼,或者為什麼專案之間存在不一致。如果您想知道同樣的事情,請繼續閱讀! 什麼是 CommonJS? CommonJS 是一組用於...
    程式設計 發佈於2024-11-07
  • 使用鏡像部署 Vite/React 應用程式:完整指南
    使用鏡像部署 Vite/React 應用程式:完整指南
    在 GitHub Pages 上部署 Vite/React 应用程序是一个令人兴奋的里程碑,但这个过程有时会带来意想不到的挑战,特别是在处理图像和资产时。这篇博文将引导您完成整个过程,从最初的部署到解决常见问题并找到有效的解决方案。 无论您是初学者还是有经验的人,本指南都将帮助您避免常见的陷阱,并...
    程式設計 發佈於2024-11-07
  • 我如何在我的 React 應用程式中優化 API 呼叫
    我如何在我的 React 應用程式中優化 API 呼叫
    作为 React 开发者,我们经常面临需要通过 API 同步多个快速状态变化的场景。对每一个微小的变化进行 API 调用可能效率低下,并且会给客户端和服务器带来负担。这就是去抖和巧妙的状态管理发挥作用的地方。在本文中,我们将构建一个自定义 React 钩子,通过合并有效负载和去抖 API 调用来捕获...
    程式設計 發佈於2024-11-07
  • 我們走吧!
    我們走吧!
    為什麼你需要嘗試 GO Go 是一種快速、輕量級、靜態類型的編譯語言,非常適合建立高效、可靠的應用程式。它的簡單性和簡潔的語法使其易於學習和使用,特別是對於新手來說。 Go 的突出功能包括內建的 goroutine 並發性、強大的標準庫以及用於程式碼格式化、測試和依賴管理的強大工具...
    程式設計 發佈於2024-11-06
  • 如何將 PNG 圖像編碼為 CSS 資料 URI 的 Base64?
    如何將 PNG 圖像編碼為 CSS 資料 URI 的 Base64?
    在CSS 資料URI 中對PNG 圖像使用Base64 編碼為了使用資料URI 將PNG 圖片嵌入到CSS 樣式表中,PNG資料必須先編碼為Base64 格式。此技術允許將外部圖像檔案直接包含在樣式表中。 Unix 命令列解決方案:base64 -i /path/to/image.png此指令將輸出...
    程式設計 發佈於2024-11-06
  • API 每小時資料的響應式 JavaScript 輪播
    API 每小時資料的響應式 JavaScript 輪播
    I almost mistook an incomplete solution for a finished one and moved on to work on other parts of my weather app! While working on the carousel that w...
    程式設計 發佈於2024-11-06
  • 用於 Web 開發的 PHP 和 JavaScript 之間的主要差異是什麼?
    用於 Web 開發的 PHP 和 JavaScript 之間的主要差異是什麼?
    PHP 與 JavaScript:伺服器端與客戶端 PHP 的作用與 JavaScript 不同。 PHP 運行在伺服器端。伺服器運行應用程式。除此之外,它還處理表單。當您提交表單時,PHP 會對其進行處理。另一方面,JavaScript 是客戶端的。它在瀏覽器中運行。它處理頁面互...
    程式設計 發佈於2024-11-06
  • 如何在 C++ 中迭代結構和類別成員以在運行時存取它們的名稱和值?
    如何在 C++ 中迭代結構和類別成員以在運行時存取它們的名稱和值?
    迭代結構體和類別成員在 C 中,可以迭代結構體或類別的成員來檢索它們的名稱和價值觀。以下是實現此目的的幾種方法:使用巨集REFLECTABLE 巨集可用於定義允許自省的結構。該巨集將結構體的成員定義為以逗號分隔的類型名稱對清單。例如:struct A { REFLECTABLE ( ...
    程式設計 發佈於2024-11-06
  • 如果需要準確答案,請避免浮動和雙精度
    如果需要準確答案,請避免浮動和雙精度
    float 和 double 問題: 專為科學和數學計算而設計,執行二元浮點運算。 不適合貨幣計算或需要精確答案的情況。 無法準確表示10的負次方,例如0.1,從而導致錯誤。 範例1: 減去美元金額時計算錯誤: System.out.println(1.03 - 0.42); // Resu...
    程式設計 發佈於2024-11-06
  • 在 Go 中使用 WebSocket 進行即時通信
    在 Go 中使用 WebSocket 進行即時通信
    构建需要实时更新的应用程序(例如聊天应用程序、实时通知或协作工具)需要一种比传统 HTTP 更快、更具交互性的通信方法。这就是 WebSockets 发挥作用的地方!今天,我们将探讨如何在 Go 中使用 WebSocket,以便您可以向应用程序添加实时功能。 在这篇文章中,我们将介绍: WebSoc...
    程式設計 發佈於2024-11-06
  • 如何在 Python 中使用代理程式運行 Selenium Webdriver?
    如何在 Python 中使用代理程式運行 Selenium Webdriver?
    使用Python 中的代理程式執行Selenium Webdriver當您嘗試將Selenium Webdriver 腳本匯出為Python 腳本並從命令列執行時,可能會遇到在使用代理的情況下出現錯誤。本文旨在解決此問題,提供使用代理有效運行腳本的解決方案。 代理整合要使用代理程式來執行 Selen...
    程式設計 發佈於2024-11-06
  • || 什麼時候運算子充當 JavaScript 中的預設運算子?
    || 什麼時候運算子充當 JavaScript 中的預設運算子?
    理解|| 的目的JavaScript 中非布林運算元的運算子在JavaScript 中,||運算子通常稱為邏輯OR 運算符,通常用於計算布林表達式。但是,您可能會遇到 || 的情況。運算符與非布林值一起使用。 在這種情況下,||運算子的行為類似於「預設」運算子。它不傳回布林值,而是根據某些規則傳回左...
    程式設計 發佈於2024-11-06
  • 探索 Java 23 的新特性
    探索 Java 23 的新特性
    親愛的開發者、程式設計愛好者和學習者, Java 開發工具包 (JDK) 23 已正式發布(2024/09/17 正式發布),標誌著 Java 程式語言發展的另一個重要里程碑。此最新更新引入了大量令人興奮的功能和增強功能,旨在改善開發人員體驗、效能和模組化。 在本文中,我將分享 JDK 23 的一...
    程式設計 發佈於2024-11-06
  • ES6 陣列解構:為什麼它沒有如預期般運作?
    ES6 陣列解構:為什麼它沒有如預期般運作?
    ES6 陣列解構:不可預見的行為在ES6 中,陣列的解構賦值可能會導致意外的結果,讓程式設計師感到困惑。下面的程式碼說明了一個這樣的實例:let a, b, c [a, b] = ['A', 'B'] [b, c] = ['BB', 'C'] console.log(`a=${a} b=${b} c...
    程式設計 發佈於2024-11-06
  • 如何調整圖像大小以適合瀏覽器視窗而不變形?
    如何調整圖像大小以適合瀏覽器視窗而不變形?
    調整圖片大小以適應瀏覽器視窗而不失真調整圖片大小以適應瀏覽器視窗是一項看似簡單的解決方案的常見任務。然而,遵守特定要求(例如保留比例和避免裁剪)可能會帶來挑戰。 沒有滾動條和 Javascript 的解決方案(僅限 CSS)<html> <head> <style&...
    程式設計 發佈於2024-11-06

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3