דילוג לתוכן
  • דף הבית
  • קטגוריות
  • פוסטים אחרונים
  • משתמשים
  • חיפוש
  • חוקי הפורום
כיווץ
תחומים

תחומים - פורום חרדי מקצועי

💡 רוצה לזכור קריאת שמע בזמן? לחץ כאן!
  1. דף הבית
  2. תכנות
  3. קריאה אסינכרונית משרת HTTP בGO

קריאה אסינכרונית משרת HTTP בGO

מתוזמן נעוץ נעול הועבר תכנות
43 פוסטים 4 כותבים 788 צפיות 3 עוקבים
  • מהישן לחדש
  • מהחדש לישן
  • הכי הרבה הצבעות
תגובה
  • תגובה כנושא
התחברו כדי לפרסם תגובה
נושא זה נמחק. רק משתמשים עם הרשאות מתאימות יוכלו לצפות בו.
  • dovidD dovid

    @yossiz ענית רק על השימוש שדורס את המיקום המדוייק בזיכרון.
    אבל למה המשתנה החדש מושפע ממיקום הבתים של הטיפוס?

    yossizY מחובר
    yossizY מחובר
    yossiz
    כתב ב נערך לאחרונה על ידי yossiz
    #16

    @dovid אם הבנתי נכון מה שאתה שואל אז התשובה היא שמשתנה מסוג string ב-GO לא מכיל את הבייטים של המחרוזת, הוא רק מצביע למקום בזכרון. לכן על אף שלכל קריאה ל-myfunc מיוצר string חדש, אבל כולם מצביעים על אותו איזור בזיכרון.
    עיין כאן: https://www.reddit.com/r/golang/comments/57ica9

    📧 יוסי@מייל.קום | 🌎 בלוג | ☕ קפה

    dovidD תגובה 1 תגובה אחרונה
    0
    • yossizY yossiz

      @dovid אם הבנתי נכון מה שאתה שואל אז התשובה היא שמשתנה מסוג string ב-GO לא מכיל את הבייטים של המחרוזת, הוא רק מצביע למקום בזכרון. לכן על אף שלכל קריאה ל-myfunc מיוצר string חדש, אבל כולם מצביעים על אותו איזור בזיכרון.
      עיין כאן: https://www.reddit.com/r/golang/comments/57ica9

      dovidD מחובר
      dovidD מחובר
      dovid
      ניהול
      כתב ב נערך לאחרונה על ידי dovid
      #17

      @yossiz אני שואל איך יכול להיות שהnumber נהרס ע"י גישה ישירה לזיכרון לtype של הctx.
      הרי הוא עותק. שהרי כשאתה משים משתנה מחרוזת למשתנה אחר זה כן כתובת שונה ותוכן בלתי תלוי, אז מה זה שונה.
      בכל מקרה גם בשימוש בunsafe לא מתקבל על הדעת שיהיה דרך בשפה עילית מודרנית לשנות ערכים של זיכרון שלא באחריות הקוד שלי, אני ממש לא מבין איך זה ייתכן.
      אני מבין שאני מפספס משהו, מה קורה כעושים number:= ctx.XXX.

      • מנטור אישי בתכנות והמסתעף – להתקדם לשלב הבא!
      • בכל נושא אפשר ליצור קשר dovid@tchumim.com
      yossizY תגובה 1 תגובה אחרונה
      1
      • dovidD dovid

        @yossiz אני שואל איך יכול להיות שהnumber נהרס ע"י גישה ישירה לזיכרון לtype של הctx.
        הרי הוא עותק. שהרי כשאתה משים משתנה מחרוזת למשתנה אחר זה כן כתובת שונה ותוכן בלתי תלוי, אז מה זה שונה.
        בכל מקרה גם בשימוש בunsafe לא מתקבל על הדעת שיהיה דרך בשפה עילית מודרנית לשנות ערכים של זיכרון שלא באחריות הקוד שלי, אני ממש לא מבין איך זה ייתכן.
        אני מבין שאני מפספס משהו, מה קורה כעושים number:= ctx.XXX.

        yossizY מחובר
        yossizY מחובר
        yossiz
        כתב ב נערך לאחרונה על ידי yossiz
        #18

        @dovid אמר בקריאה אסינכרונית משרת HTTP בGO:

        שהרי כשאתה משים משתנה מחרוזת למשתנה אחר זה כן כתובת שונה ותוכן בלתי תלוי, אז מה זה שונה

        הבייטים של המחרוזת הם אותם בייטים, אממה הכתובת של המשתנה הוא לא הכתובת של הבייטים אלא הכתובת של המצביע. (ומכיון ש-string ב-GO הוא immutable - בלי משחקים ב-unsafe - זה בטוח לגמרי, אבל ברגע שמשחקים עם הבייטים עצמם על ידי קוד unsafe כאן יתחילו בעיות)

        תעשה ניסוי קטן:

        package main
        
        import (
        	"fmt"
        	"unsafe"
        )
        
        func main() {
        	b := []byte("ABC")
        	s := *(*string)(unsafe.Pointer(&b))
        	s2 := s
        	s3 := string(b) // this is safe (it makes a copy of the original bytes)
        	b[0] = 'X'
        	b[1] = 'Y'
        	b[2] = 'Z'
        	fmt.Println(s)
        	fmt.Println(s2)
        	fmt.Println(s3) 
        }
        

        https://play.golang.org/p/EpPwsoM-z8g

        זה פחות או יותר מה שקורה בתוכנה של @nigun

        📧 יוסי@מייל.קום | 🌎 בלוג | ☕ קפה

        nigunN תגובה 1 תגובה אחרונה
        2
        • yossizY yossiz

          @dovid אמר בקריאה אסינכרונית משרת HTTP בGO:

          שהרי כשאתה משים משתנה מחרוזת למשתנה אחר זה כן כתובת שונה ותוכן בלתי תלוי, אז מה זה שונה

          הבייטים של המחרוזת הם אותם בייטים, אממה הכתובת של המשתנה הוא לא הכתובת של הבייטים אלא הכתובת של המצביע. (ומכיון ש-string ב-GO הוא immutable - בלי משחקים ב-unsafe - זה בטוח לגמרי, אבל ברגע שמשחקים עם הבייטים עצמם על ידי קוד unsafe כאן יתחילו בעיות)

          תעשה ניסוי קטן:

          package main
          
          import (
          	"fmt"
          	"unsafe"
          )
          
          func main() {
          	b := []byte("ABC")
          	s := *(*string)(unsafe.Pointer(&b))
          	s2 := s
          	s3 := string(b) // this is safe (it makes a copy of the original bytes)
          	b[0] = 'X'
          	b[1] = 'Y'
          	b[2] = 'Z'
          	fmt.Println(s)
          	fmt.Println(s2)
          	fmt.Println(s3) 
          }
          

          https://play.golang.org/p/EpPwsoM-z8g

          זה פחות או יותר מה שקורה בתוכנה של @nigun

          nigunN מנותק
          nigunN מנותק
          nigun
          כתב ב נערך לאחרונה על ידי nigun
          #19

          @yossiz
          נראה לי שעכשיו הבנתי קצת מה קורה כאן
          המשתנה number הוא מערך של bytes
          והוא מצביע על מערך אחר של bytes (שנמצא בCtx ???)
          כשאני מדפיס בפעם הראשונה את number זה מיד אחרי שקראתי לfunc(c *fiber.Ctx)
          ולפני שנעשה קריאה חדשה לfunc(c *fiber.Ctx)
          ולכן הוא מדפיס את הערך האחרון (שהוא הנכון)
          אבל בפעם השניה הערך הוא המערך במקורי הוא [57 49] שזה "19" (כי זה היה הקריאה האחרונה)
          אבל המצביע number נשאר עם מערך של איבר אחד
          לכן הוא ממיר לסטרינג רק את האיבר הראשון במערך ולכן הוא מדפיס "1"
          עד שהוא מגיע למערכים בני שני איברים (כי בקריאה המקורית זה היה עם שני ספרות) ואז הוא מדפיס "19"
          והסיבה שהוא נשאר מצביע ולא משתנה חדש זה בגלל שהוא נוצר עם unsafe (שנשאר להצביע תמיד על הכתובת הראשונה)

          `

          מייל: nigun@duck.com

          yossizY תגובה 1 תגובה אחרונה
          2
          • dovidD מחובר
            dovidD מחובר
            dovid
            ניהול
            כתב ב נערך לאחרונה על ידי dovid
            #20

            @yossiz אכן הבנתי יותר (לא לגמרי כי אני ממש לא מחבב ביטים וברזלים). לפ"ז שרשור או הפונקציה string פותרת את הבעיה בדוגמה של @nigun.
            תודה רבה!
            עכ"פ אפשר לסכם שטעות של מתכנת בספריה בגו יכולה לשבש קוד בכל הפרוייקט שמשתמש בה.

            • מנטור אישי בתכנות והמסתעף – להתקדם לשלב הבא!
            • בכל נושא אפשר ליצור קשר dovid@tchumim.com
            nigunN תגובה 1 תגובה אחרונה
            2
            • dovidD dovid

              @yossiz אכן הבנתי יותר (לא לגמרי כי אני ממש לא מחבב ביטים וברזלים). לפ"ז שרשור או הפונקציה string פותרת את הבעיה בדוגמה של @nigun.
              תודה רבה!
              עכ"פ אפשר לסכם שטעות של מתכנת בספריה בגו יכולה לשבש קוד בכל הפרוייקט שמשתמש בה.

              nigunN מנותק
              nigunN מנותק
              nigun
              כתב ב נערך לאחרונה על ידי
              #21

              @dovid אמר בקריאה אסינכרונית משרת HTTP בGO:

              עכ"פ אפשר לסכם שטעות של מתכנת בספריה בגו יכולה לשבש קוד בכל הפרוייקט שמשתמש בה.

              ובשפות אחרות לא יכול להיות כזה מצב?

              מייל: nigun@duck.com

              dovidD תגובה 1 תגובה אחרונה
              0
              • nigunN nigun

                @dovid אמר בקריאה אסינכרונית משרת HTTP בGO:

                עכ"פ אפשר לסכם שטעות של מתכנת בספריה בגו יכולה לשבש קוד בכל הפרוייקט שמשתמש בה.

                ובשפות אחרות לא יכול להיות כזה מצב?

                dovidD מחובר
                dovidD מחובר
                dovid
                ניהול
                כתב ב נערך לאחרונה על ידי dovid
                #22

                @nigun עד כמה שחשבתי עד היום...
                אני כעת בדקתי וזה אכן קורה גם בC#:

                void Main()
                {
                    var t = new strTest();
                    var str = t.GetStr();
                    t.Change();
                    Console.WriteLine(str);
                }
                
                
                public class strTest
                {
                    string str = "ABC";
                
                    public string GetStr() => str;
                
                    public void Change()
                    {
                        unsafe
                        {
                            fixed (char* p = str)
                                p[0] = 'a';
                        }
                    }
                }
                

                אכן לא תמיד חוסר ידע שלי זה אשמת השפות 🙂

                • מנטור אישי בתכנות והמסתעף – להתקדם לשלב הבא!
                • בכל נושא אפשר ליצור קשר dovid@tchumim.com
                תגובה 1 תגובה אחרונה
                3
                • nigunN nigun

                  @yossiz
                  נראה לי שעכשיו הבנתי קצת מה קורה כאן
                  המשתנה number הוא מערך של bytes
                  והוא מצביע על מערך אחר של bytes (שנמצא בCtx ???)
                  כשאני מדפיס בפעם הראשונה את number זה מיד אחרי שקראתי לfunc(c *fiber.Ctx)
                  ולפני שנעשה קריאה חדשה לfunc(c *fiber.Ctx)
                  ולכן הוא מדפיס את הערך האחרון (שהוא הנכון)
                  אבל בפעם השניה הערך הוא המערך במקורי הוא [57 49] שזה "19" (כי זה היה הקריאה האחרונה)
                  אבל המצביע number נשאר עם מערך של איבר אחד
                  לכן הוא ממיר לסטרינג רק את האיבר הראשון במערך ולכן הוא מדפיס "1"
                  עד שהוא מגיע למערכים בני שני איברים (כי בקריאה המקורית זה היה עם שני ספרות) ואז הוא מדפיס "19"
                  והסיבה שהוא נשאר מצביע ולא משתנה חדש זה בגלל שהוא נוצר עם unsafe (שנשאר להצביע תמיד על הכתובת הראשונה)

                  `

                  yossizY מחובר
                  yossizY מחובר
                  yossiz
                  כתב ב נערך לאחרונה על ידי
                  #23

                  @nigun אמר בקריאה אסינכרונית משרת HTTP בGO:

                  נראה לי שעכשיו הבנתי קצת מה קורה כאן

                  בגדול אני מסכים עם ההסבר למרות שהייתי משנה טיפה את הנוסח.

                  המשתנה number הוא מערך של bytes
                  והוא מצביע על מערך אחר של bytes

                  המשתנה number הוא string. ותמיד משתנה מסוג string ב-GO הוא struct שיש בו 2 שדות, 1) מצביע לבייטים של המחרוזת 2) מספר שאומר מה אורך המחרוזת (כמה בייטים לקחת מהמיקום ששדה 1 מצביע עליו)
                  עכשיו, אם אתה מייצר סטרינג רגיל, סביבת ההרצה דואגת שהסטרינג יהיה immutable (שאין דרך - בלי קוד unsafe - לשנות את הערכים של הבייטים שעליו הוא מצביע), ולכן, אם סביבת ההרצה רואה שיצרת ממערך בייטים שהוא הרי mutable, הוא ידאוג להעתיק את הבייטים המקוריים למיקום חדש שלא ניתן לגישה מקוד רגיל, אבל אם ייצרת אותו ממערך בייטים עם המילה unsafe זה כאילו להגיד לסביבת ההרצה "אל תדאג, אני יודע מה אני עושה, אל תתערב לי" ואז אפשר לשנות את המערך המקורי ובזה לשנות את המחרוזת שהסטרינג ידפיס.

                  עד שהוא מגיע למערכים בני שני איברים (כי בקריאה המקורית זה היה עם שני ספרות) ואז הוא מדפיס "19"

                  יפה! לנקודה הזאת לא שמתי לב, זה החלק שהיה חסר לי בפאזל.

                  והסיבה שהוא נשאר מצביע ולא משתנה חדש זה בגלל שהוא נוצר עם unsafe

                  לא ממש מדוייק, תמיד string יהיה מצביע, אבל כנ"ל באריכות, ההבדל הוא אם הוא מצביע למיקום שנגיש מקוד אחר או לא

                  מקוה שהסברתי ברור...

                  📧 יוסי@מייל.קום | 🌎 בלוג | ☕ קפה

                  nigunN תגובה 1 תגובה אחרונה
                  3
                  • nigunN nigun

                    @dovid
                    קודם כל אני מופתע שאתה מונח טוב בGO (מספיק בשביל לדבג)
                    בדקתי עכשיו מה קורה אם אני משתמש בשרת fasthttp שעליו פיבר מבוסס (הוא גם משתמש בctx)
                    ושם התוצאה תקינה
                    כנראה שהבעיה היא בפיבר

                    
                    package main
                    
                    import (
                            "flag"
                            "fmt"
                            "log"
                            "time"
                    
                            "github.com/valyala/fasthttp"
                    )
                    
                    var (
                            addr     = flag.String("addr", ":3000", "TCP address to listen to")
                            compress = flag.Bool("compress", false, "Whether to enable transparent response compression")
                    )
                    
                    func main() {
                            flag.Parse()
                    
                            h := requestHandler
                            if *compress {
                                    h = fasthttp.CompressHandler(h)
                            }
                    
                            if err := fasthttp.ListenAndServe(*addr, h); err != nil {
                                    log.Fatalf("Error in ListenAndServe: %s", err)
                            }
                    }
                    
                    func requestHandler(ctx *fasthttp.RequestCtx) {
                            go myfunc(string(ctx.Path()))
                            fmt.Fprintf(ctx, "Requested path is %q\n", ctx.Path())
                    }
                    func myfunc(number string) {
                            fmt.Printf("number is %s \n", number)
                            time.Sleep(1 * time.Second)
                            fmt.Printf("number is now %s \n", number)
                    }
                    
                    
                    yossizY מחובר
                    yossizY מחובר
                    yossiz
                    כתב ב נערך לאחרונה על ידי yossiz
                    #24

                    @nigun אמר בקריאה אסינכרונית משרת HTTP בGO:

                    בדקתי עכשיו מה קורה אם אני משתמש בשרת fasthttp שעליו פיבר מבוסס (הוא גם משתמש בctx)
                    ושם התוצאה תקינה
                    כנראה שהבעיה היא בפיבר

                    עיין כאן איך אפשר לממש את הבאג גם ב-fasthttp.
                    הדוגמה שלך עובד טוב כי הפונקציה string מייצר string חדש בצורה בטוחה.

                    @dovid אמר בקריאה אסינכרונית משרת HTTP בGO:

                    אני כעת בדקתי וזה אכן קורה גם בC#:

                    השימוש במילת unsafe מחזיר אותך אחורה לימי ה-C שיש לך שליטה מלאה על כל מרחב הזיכרון של התהליך
                    ב-JS אסור בהחלט שזה יקרה כי כך יהיה אפשר לפרוץ החוצה מארגז החול של הדפדפן, ולכן באמת אין unsafe ב-JS.

                    📧 יוסי@מייל.קום | 🌎 בלוג | ☕ קפה

                    תגובה 1 תגובה אחרונה
                    3
                    • yossizY yossiz

                      @nigun אמר בקריאה אסינכרונית משרת HTTP בGO:

                      נראה לי שעכשיו הבנתי קצת מה קורה כאן

                      בגדול אני מסכים עם ההסבר למרות שהייתי משנה טיפה את הנוסח.

                      המשתנה number הוא מערך של bytes
                      והוא מצביע על מערך אחר של bytes

                      המשתנה number הוא string. ותמיד משתנה מסוג string ב-GO הוא struct שיש בו 2 שדות, 1) מצביע לבייטים של המחרוזת 2) מספר שאומר מה אורך המחרוזת (כמה בייטים לקחת מהמיקום ששדה 1 מצביע עליו)
                      עכשיו, אם אתה מייצר סטרינג רגיל, סביבת ההרצה דואגת שהסטרינג יהיה immutable (שאין דרך - בלי קוד unsafe - לשנות את הערכים של הבייטים שעליו הוא מצביע), ולכן, אם סביבת ההרצה רואה שיצרת ממערך בייטים שהוא הרי mutable, הוא ידאוג להעתיק את הבייטים המקוריים למיקום חדש שלא ניתן לגישה מקוד רגיל, אבל אם ייצרת אותו ממערך בייטים עם המילה unsafe זה כאילו להגיד לסביבת ההרצה "אל תדאג, אני יודע מה אני עושה, אל תתערב לי" ואז אפשר לשנות את המערך המקורי ובזה לשנות את המחרוזת שהסטרינג ידפיס.

                      עד שהוא מגיע למערכים בני שני איברים (כי בקריאה המקורית זה היה עם שני ספרות) ואז הוא מדפיס "19"

                      יפה! לנקודה הזאת לא שמתי לב, זה החלק שהיה חסר לי בפאזל.

                      והסיבה שהוא נשאר מצביע ולא משתנה חדש זה בגלל שהוא נוצר עם unsafe

                      לא ממש מדוייק, תמיד string יהיה מצביע, אבל כנ"ל באריכות, ההבדל הוא אם הוא מצביע למיקום שנגיש מקוד אחר או לא

                      מקוה שהסברתי ברור...

                      nigunN מנותק
                      nigunN מנותק
                      nigun
                      כתב ב נערך לאחרונה על ידי
                      #25

                      @yossiz אמר בקריאה אסינכרונית משרת HTTP בGO:

                      לא ממש מדוייק, תמיד string יהיה מצביע, אבל כנ"ל באריכות, ההבדל הוא אם הוא מצביע למיקום שנגיש מקוד אחר או לא

                      תודה על כל ההסברים המדוייקים
                      רק לא הבנתי את הקטע האחרון
                      האם כל פעם שאני יוצר סטרינג חדש (רגיל) הוא מצביע לכתובת חדשה, ואם משתמשים בunsafe אז הוא מצביע על המקורי
                      או שזה עובד אחרת?

                      מייל: nigun@duck.com

                      yossizY תגובה 1 תגובה אחרונה
                      0
                      • nigunN nigun

                        @yossiz אמר בקריאה אסינכרונית משרת HTTP בGO:

                        לא ממש מדוייק, תמיד string יהיה מצביע, אבל כנ"ל באריכות, ההבדל הוא אם הוא מצביע למיקום שנגיש מקוד אחר או לא

                        תודה על כל ההסברים המדוייקים
                        רק לא הבנתי את הקטע האחרון
                        האם כל פעם שאני יוצר סטרינג חדש (רגיל) הוא מצביע לכתובת חדשה, ואם משתמשים בunsafe אז הוא מצביע על המקורי
                        או שזה עובד אחרת?

                        yossizY מחובר
                        yossizY מחובר
                        yossiz
                        כתב ב נערך לאחרונה על ידי yossiz
                        #26

                        @nigun אמר בקריאה אסינכרונית משרת HTTP בGO:

                        האם כל פעם שאני יוצר סטרינג חדש (רגיל) הוא מצביע לכתובת חדשה, ואם משתמשים בunsafe אז הוא מצביע על המקורי
                        או שזה עובד אחרת?

                        זה עובד אחרת, זה תלוי אם סביבת ההרצה הקומפיילר חוששת שהבייטים ישתנו, משום שלכל סטרינג יש חוזה (implicit contract) שהוא לא הולך להשתנות (immutable), וסביבת ההרצה הקומפיילר דואגת לאכוף את זה. (אבל בשימוש ב-unsafe אתה אומר לסביבת ההרצה קומפיילר "אל תדאג, אני יודע מה אני עושה, אל תתערב לי")
                        (אפשר לבדוק את זה על ידי הדפסת תוכן אובייקט ה-string כמו כאן)
                        (או שאפשר לקרוא את קוד המקור של סביבת ההרצה הקומפיילר...)

                        package main
                        
                        import (
                        	"fmt"
                        	"reflect"
                        	"unsafe"
                        )
                        
                        func main() {
                        	b := []byte("ABC")
                        	s := *(*string)(unsafe.Pointer(&b)) // מצביע על הבייטים המקוריים
                        	s2 := s                             // עדיין מצביע על הבייטים המקוריים
                        	s3 := string(b)                     // מעתיק את הבייטים המקוריים ומצביע על המיקום של הבייטים החדשים
                        	s4 := s3                            // לא מעתיק את הבייטים המקוריים כי סביבת ההרצה בטוח שהבייטים המקוריים לא ישתנו
                        	s5 := string(s4)                    // עדיין לא מעתיק וכנ"ל
                        	dumpStringAddr(s)
                        	dumpStringAddr(s2)
                        	dumpStringAddr(s3)
                        	dumpStringAddr(s4)
                        	dumpStringAddr(s5)
                        }
                        
                        func dumpStringAddr(s string) {
                        	address := (*reflect.StringHeader)(unsafe.Pointer(&s)).Data
                        	fmt.Printf("%08x\n", address)
                        }
                        

                        https://play.golang.org/p/QCOx7_DmJov

                        📧 יוסי@מייל.קום | 🌎 בלוג | ☕ קפה

                        nigunN תגובה 1 תגובה אחרונה
                        3
                        • yossizY yossiz

                          @nigun אמר בקריאה אסינכרונית משרת HTTP בGO:

                          האם כל פעם שאני יוצר סטרינג חדש (רגיל) הוא מצביע לכתובת חדשה, ואם משתמשים בunsafe אז הוא מצביע על המקורי
                          או שזה עובד אחרת?

                          זה עובד אחרת, זה תלוי אם סביבת ההרצה הקומפיילר חוששת שהבייטים ישתנו, משום שלכל סטרינג יש חוזה (implicit contract) שהוא לא הולך להשתנות (immutable), וסביבת ההרצה הקומפיילר דואגת לאכוף את זה. (אבל בשימוש ב-unsafe אתה אומר לסביבת ההרצה קומפיילר "אל תדאג, אני יודע מה אני עושה, אל תתערב לי")
                          (אפשר לבדוק את זה על ידי הדפסת תוכן אובייקט ה-string כמו כאן)
                          (או שאפשר לקרוא את קוד המקור של סביבת ההרצה הקומפיילר...)

                          package main
                          
                          import (
                          	"fmt"
                          	"reflect"
                          	"unsafe"
                          )
                          
                          func main() {
                          	b := []byte("ABC")
                          	s := *(*string)(unsafe.Pointer(&b)) // מצביע על הבייטים המקוריים
                          	s2 := s                             // עדיין מצביע על הבייטים המקוריים
                          	s3 := string(b)                     // מעתיק את הבייטים המקוריים ומצביע על המיקום של הבייטים החדשים
                          	s4 := s3                            // לא מעתיק את הבייטים המקוריים כי סביבת ההרצה בטוח שהבייטים המקוריים לא ישתנו
                          	s5 := string(s4)                    // עדיין לא מעתיק וכנ"ל
                          	dumpStringAddr(s)
                          	dumpStringAddr(s2)
                          	dumpStringAddr(s3)
                          	dumpStringAddr(s4)
                          	dumpStringAddr(s5)
                          }
                          
                          func dumpStringAddr(s string) {
                          	address := (*reflect.StringHeader)(unsafe.Pointer(&s)).Data
                          	fmt.Printf("%08x\n", address)
                          }
                          

                          https://play.golang.org/p/QCOx7_DmJov

                          nigunN מנותק
                          nigunN מנותק
                          nigun
                          כתב ב נערך לאחרונה על ידי
                          #27

                          @yossiz
                          מה הצורה הכי נוחה ליצור משתנה חדש אחרי שכבר המשתנה הקודם נשמר בunsafe
                          אני עשיתי המרה לביטים ואז המרה חזרה לסטרינג השאלה האם יש משהו יותר אלגנטי?

                            app.Get("/:number", func(c *fiber.Ctx) {
                                          number := c.Path()
                                          str := []byte(number)
                                          go myfunc(string(str) )
                          
                          

                          מייל: nigun@duck.com

                          dovidD תגובה 1 תגובה אחרונה
                          1
                          • nigunN nigun

                            @yossiz
                            מה הצורה הכי נוחה ליצור משתנה חדש אחרי שכבר המשתנה הקודם נשמר בunsafe
                            אני עשיתי המרה לביטים ואז המרה חזרה לסטרינג השאלה האם יש משהו יותר אלגנטי?

                              app.Get("/:number", func(c *fiber.Ctx) {
                                            number := c.Path()
                                            str := []byte(number)
                                            go myfunc(string(str) )
                            
                            
                            dovidD מחובר
                            dovidD מחובר
                            dovid
                            ניהול
                            כתב ב נערך לאחרונה על ידי dovid
                            #28

                            @nigun כבר היה בקוד של @yossiz בצורה קצרה:

                             number := string(c.Path())
                            

                            או כל שרשור גם עושה בהכרח משתנה חדש:

                            number := c.Path() + ""
                            
                            • מנטור אישי בתכנות והמסתעף – להתקדם לשלב הבא!
                            • בכל נושא אפשר ליצור קשר dovid@tchumim.com
                            yossizY תגובה 1 תגובה אחרונה
                            2
                            • dovidD dovid

                              @nigun כבר היה בקוד של @yossiz בצורה קצרה:

                               number := string(c.Path())
                              

                              או כל שרשור גם עושה בהכרח משתנה חדש:

                              number := c.Path() + ""
                              
                              yossizY מחובר
                              yossizY מחובר
                              yossiz
                              כתב ב נערך לאחרונה על ידי yossiz
                              #29

                              @dovid זה לא יעזור לו כי fiber עושה את ההמרה לסטרינג בשבילו ולא נותן אופציה של קבלת מערך בייטים כמו ש-fasthttp נותן.
                              @nigun אאל"ט, מה שעשית זה הכי טוב שיש לך בנסיבות אלו

                              📧 יוסי@מייל.קום | 🌎 בלוג | ☕ קפה

                              dovidD תגובה 1 תגובה אחרונה
                              0
                              • yossizY yossiz

                                @dovid זה לא יעזור לו כי fiber עושה את ההמרה לסטרינג בשבילו ולא נותן אופציה של קבלת מערך בייטים כמו ש-fasthttp נותן.
                                @nigun אאל"ט, מה שעשית זה הכי טוב שיש לך בנסיבות אלו

                                dovidD מחובר
                                dovidD מחובר
                                dovid
                                ניהול
                                כתב ב נערך לאחרונה על ידי dovid
                                #30

                                @yossiz לא הבנתי, הרי אם הוא משרשר את זה, אז בהכרח נוצרת כתובת חדשה, לא?
                                כמו"כ אני ניסיתי את הדוגמה הראשונה של פייבר עם שרשור וזה היה בסדר גמור. זה לא אותו נידון?

                                • מנטור אישי בתכנות והמסתעף – להתקדם לשלב הבא!
                                • בכל נושא אפשר ליצור קשר dovid@tchumim.com
                                yossizY תגובה 1 תגובה אחרונה
                                0
                                • dovidD dovid

                                  @yossiz לא הבנתי, הרי אם הוא משרשר את זה, אז בהכרח נוצרת כתובת חדשה, לא?
                                  כמו"כ אני ניסיתי את הדוגמה הראשונה של פייבר עם שרשור וזה היה בסדר גמור. זה לא אותו נידון?

                                  yossizY מחובר
                                  yossizY מחובר
                                  yossiz
                                  כתב ב נערך לאחרונה על ידי yossiz
                                  #31

                                  @dovid אמר בקריאה אסינכרונית משרת HTTP בGO:

                                  הרי אם הוא משרשר את זה, אז בהכרח נוצרת כתובת חדשה, לא

                                  לכאורה לא. כי זה אותו מחרוזת, למה ליצור כתובת חדשה.
                                  (https://play.golang.org/p/BuugrOW8xuy)

                                  כמו"כ אני ניסיתי את הדוגמה הראשונה של פייבר עם שרשור וזה היה בסדר גמור. זה לא אותו נידון?

                                  ניסיתי עכשיו על ידי שינוי שורה 14 ל-

                                  number := c.Params("number") + ""
                                  

                                  והתוצאה לא בסדר. (או שאנחנו לא מבינים אחד את השני ומדברים על דברים שונים?)

                                  📧 יוסי@מייל.קום | 🌎 בלוג | ☕ קפה

                                  dovidD תגובה 1 תגובה אחרונה
                                  0
                                  • yossizY yossiz

                                    @dovid אמר בקריאה אסינכרונית משרת HTTP בGO:

                                    הרי אם הוא משרשר את זה, אז בהכרח נוצרת כתובת חדשה, לא

                                    לכאורה לא. כי זה אותו מחרוזת, למה ליצור כתובת חדשה.
                                    (https://play.golang.org/p/BuugrOW8xuy)

                                    כמו"כ אני ניסיתי את הדוגמה הראשונה של פייבר עם שרשור וזה היה בסדר גמור. זה לא אותו נידון?

                                    ניסיתי עכשיו על ידי שינוי שורה 14 ל-

                                    number := c.Params("number") + ""
                                    

                                    והתוצאה לא בסדר. (או שאנחנו לא מבינים אחד את השני ומדברים על דברים שונים?)

                                    dovidD מחובר
                                    dovidD מחובר
                                    dovid
                                    ניהול
                                    כתב ב נערך לאחרונה על ידי
                                    #32

                                    למה ליצור חדש? כי אין לו בכלל מקום במיקום המקורי אולי. לא יודע. הנה בדוגמה שלך זה יוצר חדש כשהשרשור לא ריק.
                                    בבדיקה שלי המחרוזת ששירשרתי לא היתה ריקה, ולכן זה עבד, ככה:

                                    package main
                                    
                                    import (
                                    	"fmt"
                                    	"time"
                                    	"github.com/gofiber/fiber"
                                    )
                                    
                                    func main() {
                                    	app := fiber.New()
                                    
                                    	app.Get("/:number", func(c *fiber.Ctx) {
                                    		number := c.Params("number") + " "
                                    		go myfunc(number)
                                    		c.Send(number)
                                    	})
                                    	app.Listen(3000)
                                    }
                                    
                                    func myfunc(number string) {
                                    	fmt.Printf("number is %s \n", number)
                                    	time.Sleep(1 * time.Second)
                                    	fmt.Printf("number is now %s \n", number)
                                    }
                                    
                                    
                                    • מנטור אישי בתכנות והמסתעף – להתקדם לשלב הבא!
                                    • בכל נושא אפשר ליצור קשר dovid@tchumim.com
                                    תגובה 1 תגובה אחרונה
                                    1
                                    • nigunN מנותק
                                      nigunN מנותק
                                      nigun
                                      כתב ב נערך לאחרונה על ידי nigun
                                      #33

                                      @yossiz
                                      הם עכשיו הוציאו גירסה חדשה (למה הם התחילו מגירסה 1.0 ולא 0.1? זה כבר שאלה אחרת)
                                      שבה הם הוסיפו את האפשרות שכל הסטרינגים יהיו Immutable
                                      זה טוב, אבל נראה לי שהברירת מחדל צריך להיות הפוך ומי שרוצה יוכל להשתמש בunsafe
                                      גם יהיה נחמד אם יהיה אפשרות לשלב את שני הסוגים באותו שרת
                                      למשל שפשוט יחזירו bytes והלקוח ימיר את זה כרצונו.
                                      (אני לא כותב את זה בשרשור בגיטהאב כי אני לא בטוח שמה שאני אומר זה נכון)

                                      מייל: nigun@duck.com

                                      yossizY תגובה 1 תגובה אחרונה
                                      1
                                      • nigunN nigun

                                        @yossiz
                                        הם עכשיו הוציאו גירסה חדשה (למה הם התחילו מגירסה 1.0 ולא 0.1? זה כבר שאלה אחרת)
                                        שבה הם הוסיפו את האפשרות שכל הסטרינגים יהיו Immutable
                                        זה טוב, אבל נראה לי שהברירת מחדל צריך להיות הפוך ומי שרוצה יוכל להשתמש בunsafe
                                        גם יהיה נחמד אם יהיה אפשרות לשלב את שני הסוגים באותו שרת
                                        למשל שפשוט יחזירו bytes והלקוח ימיר את זה כרצונו.
                                        (אני לא כותב את זה בשרשור בגיטהאב כי אני לא בטוח שמה שאני אומר זה נכון)

                                        yossizY מחובר
                                        yossizY מחובר
                                        yossiz
                                        כתב ב נערך לאחרונה על ידי
                                        #34

                                        @nigun לכאורה אני מסכים לטענותיך
                                        (אני גם לא הולך לכתוב, א) ענין כזה שהוא לא טכני גרידא אלא ענין של טעם וניסיון וכו' אני לא מחזיק את עצמי כמייבין ב) אם זה היה נוגע אלי והייתי רואה פרוייקט חדש שהולך בכיוון לא טוב, לא הייתי משקיע בו יותר מדי, חכה עד שזה יהיה production ready או שימות מיתה טבעית)

                                        📧 יוסי@מייל.קום | 🌎 בלוג | ☕ קפה

                                        nigunN תגובה 1 תגובה אחרונה
                                        2
                                        • yossizY yossiz

                                          @nigun לכאורה אני מסכים לטענותיך
                                          (אני גם לא הולך לכתוב, א) ענין כזה שהוא לא טכני גרידא אלא ענין של טעם וניסיון וכו' אני לא מחזיק את עצמי כמייבין ב) אם זה היה נוגע אלי והייתי רואה פרוייקט חדש שהולך בכיוון לא טוב, לא הייתי משקיע בו יותר מדי, חכה עד שזה יהיה production ready או שימות מיתה טבעית)

                                          nigunN מנותק
                                          nigunN מנותק
                                          nigun
                                          כתב ב נערך לאחרונה על ידי
                                          #35

                                          @yossiz
                                          א. האם זה לגיטימי להציע הצעות של טעם ונוחות בגיטהאב?
                                          ב. הרעיון של להביא את אקספרס לGO, תפס הרבה באזז
                                          (תסתכל על הגרף של ההצבעות שבתחתית הREADME, ואפילו ברברסים דיברו על זה)
                                          לכן לא נראה לי שזה ימות אא"כ מישהו יעשה שם שטויות רציניות, רק מה? זה נראה שהם קצת עפים על עצמם יותר מידי.

                                          מייל: nigun@duck.com

                                          yossizY תגובה 1 תגובה אחרונה
                                          0
                                          תגובה
                                          • תגובה כנושא
                                          התחברו כדי לפרסם תגובה
                                          • מהישן לחדש
                                          • מהחדש לישן
                                          • הכי הרבה הצבעות


                                          • 1
                                          • 2
                                          • 3
                                          בא תתחבר לדף היומי!
                                          • התחברות

                                          • אין לך חשבון עדיין? הרשמה

                                          • התחברו או הירשמו כדי לחפש.
                                          • פוסט ראשון
                                            פוסט אחרון
                                          0
                                          • דף הבית
                                          • קטגוריות
                                          • פוסטים אחרונים
                                          • משתמשים
                                          • חיפוש
                                          • חוקי הפורום