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

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

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

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

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

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

    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    	path := r.URL.Path[1:]
    	go myfunc(path)
    })
    http.ListenAndServe(":4000", nil)
    

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

    var arr []string
    ...
    number := c.Params("number")
    arr = append(arr, number)
    go myfunc(number)
    c.Send(number)
    

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

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

    @יוסף-בן-שמעון
    אם זה בעיה רק בשרת של פיבר
    צריך לפתוח פניה בגיטהאב
    כי כנראה זה בעיה קריטית בשרת
    אני יתחיל לנסות לנסח את הפניה כראוי
    ויעלה את זה קודם כל באן בשביל לבדוק שאני עושה את זה נכון

    מייל: nigun@duck.com

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

      @יוסף-בן-שמעון
      אם זה בעיה רק בשרת של פיבר
      צריך לפתוח פניה בגיטהאב
      כי כנראה זה בעיה קריטית בשרת
      אני יתחיל לנסות לנסח את הפניה כראוי
      ויעלה את זה קודם כל באן בשביל לבדוק שאני עושה את זה נכון

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

      @nigun אגב, פרוייקט פייבר נראה מאוד צעיר ואולי לא מוכן לפרודקשן

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

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

        @nigun אגב, פרוייקט פייבר נראה מאוד צעיר ואולי לא מוכן לפרודקשן

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

        אני לא מבין איך זה קשור לפייבר. אני גם לא יודע לומר מה קורה. אם המבנה של התשובה בכל בקשה משותף גם השורה המודפסת הראשונה הייתה צריכה להידרס, מוכח שהפונקציה מקבלת בכל בקשה ערך שונה.
        ואם זה קשור לפייבר זה מטיל צל על כל הgo, כי הטעות הזו גורמת לקוד אחר לחלוטין לעבור באופן בלתי צפוי.

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

          הצלחתי לשחזר את הבאג.
          הפייבר עושה שימוש באותו ctx, כנראה עם נעילה (mutex וכדומה) כך שברור שאין שימוש בקודם. הבעיה שההשהיה מנטרלת את הנעילה, כלומר הפוקנציה באמת נגמרה (והיא לא ביצעה עוד את השורה המושהית) ופייבר ממשיך לבקשה הבאה.
          לגבי העתקת הערך לפונקציה שלכאורה "מנתקת" את הערך ע"י "העתקתו", אז הנה למדנו משהו על go. אלא שאני לא מצליח "ללמוד" פה, ואשמח להסבר על זה.
          (בדוגמה שלי להלן יש המחשה לבעיה אבל שמה גם ההדפסה הראשונה שגויה בגלל שאין נעילה בכלל גם בהתחלה, משא"כ בבקשות הhttp של פייבר שיש נעילה עד לסיום הפונקציה המטפלת של הget. משא"כ ההדפסה הראשונה משוחררת מנעילה ומבוצעת מיידית).

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

          מה שקורה פה זה עם לולאה, מעבירים מצביע למבנה לפונקציה, שהיא לכאורה מנתקת את הערך ע"י השמה למשתנה אבל זה לא עוזר.

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

            טעיתי. אני כעת רואה שgorutine מתחילות לפעול רק אחרי סיום הקוד הנוכחי, כלומר הbridge(&p) ייקרא עשרה פעמים רק אחרי השינוי האחרון של המאפיין name כך שהתוצאה הגיונית לגמרי.

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

              @nigun אגב, פרוייקט פייבר נראה מאוד צעיר ואולי לא מוכן לפרודקשן

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

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

              @nigun אגב, פרוייקט פייבר נראה מאוד צעיר ואולי לא מוכן לפרודקשן

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

              מייל: nigun@duck.com

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

                טעיתי. אני כעת רואה שgorutine מתחילות לפעול רק אחרי סיום הקוד הנוכחי, כלומר הbridge(&p) ייקרא עשרה פעמים רק אחרי השינוי האחרון של המאפיין name כך שהתוצאה הגיונית לגמרי.

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

                @dovid לא הבנתי איפה אתה אוחז אחרי הפלפול
                לכאורה המקרה של @nigun לא דומה לדוגמה שלך, כי אצלך המשתנה לא מקבל ערך אחר באמצע ריצת הפונקציה.
                ואם כן תמוה איך בקוד של @nigun המחרוזת (שהוא value type, לא?) משתנה באמצע ריצה.

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

                dovidD תגובה 1 תגובה אחרונה
                2
                • dovidD dovid

                  הצלחתי לשחזר את הבאג.
                  הפייבר עושה שימוש באותו ctx, כנראה עם נעילה (mutex וכדומה) כך שברור שאין שימוש בקודם. הבעיה שההשהיה מנטרלת את הנעילה, כלומר הפוקנציה באמת נגמרה (והיא לא ביצעה עוד את השורה המושהית) ופייבר ממשיך לבקשה הבאה.
                  לגבי העתקת הערך לפונקציה שלכאורה "מנתקת" את הערך ע"י "העתקתו", אז הנה למדנו משהו על go. אלא שאני לא מצליח "ללמוד" פה, ואשמח להסבר על זה.
                  (בדוגמה שלי להלן יש המחשה לבעיה אבל שמה גם ההדפסה הראשונה שגויה בגלל שאין נעילה בכלל גם בהתחלה, משא"כ בבקשות הhttp של פייבר שיש נעילה עד לסיום הפונקציה המטפלת של הget. משא"כ ההדפסה הראשונה משוחררת מנעילה ומבוצעת מיידית).

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

                  מה שקורה פה זה עם לולאה, מעבירים מצביע למבנה לפונקציה, שהיא לכאורה מנתקת את הערך ע"י השמה למשתנה אבל זה לא עוזר.

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

                  @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)
                  }
                  
                  

                  מייל: nigun@duck.com

                  י yossizY 2 תגובות תגובה אחרונה
                  0
                  • yossizY yossiz

                    @dovid לא הבנתי איפה אתה אוחז אחרי הפלפול
                    לכאורה המקרה של @nigun לא דומה לדוגמה שלך, כי אצלך המשתנה לא מקבל ערך אחר באמצע ריצת הפונקציה.
                    ואם כן תמוה איך בקוד של @nigun המחרוזת (שהוא value type, לא?) משתנה באמצע ריצה.

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

                    @yossiz אתה צודק, זה קושיא על go, רק שלא הצלחתי לשחזר את זה (בלי פיבר).

                    • מנטור אישי בתכנות והמסתעף – להתקדם לשלב הבא!
                    • בכל נושא אפשר ליצור קשר dovid@tchumim.com
                    תגובה 1 תגובה אחרונה
                    0
                    • 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)
                      }
                      
                      
                      י מנותק
                      י מנותק
                      יוסף בן שמעון
                      כתב ב נערך לאחרונה על ידי
                      #12
                      פוסט זה נמחק!
                      תגובה 1 תגובה אחרונה
                      5
                      • yossizY מחובר
                        yossizY מחובר
                        yossiz
                        כתב ב נערך לאחרונה על ידי yossiz
                        #13

                        מצאתי את מקור הבעיה
                        https://github.com/gofiber/fiber/blob/efe89d243de6d8cf964581f5832b4341e2baa427/utils.go#L128-L130
                        הפונקציה הנ"ל בשימוש רחב בקובץ context.go
                        וזה הרי כבר מתועד בתיעוד הרשמי של fasthttp שאסור להשתמש ב-ctx אחרי שה-handler חוזר. וכן בהערה כאן, ועיין עוד: https://github.com/valyala/fasthttp/issues/146

                        אם fiber לא היו מחפים על השימוש ב-byte array על ידי המרה בצורה לא בטוחה למחרוזת היה יותר קל למצוא את הבעיה.

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

                        אז הנה למדנו משהו על go

                        לפי דרכי למדנו שלא כדאי להשתמש ב-unsafe בלי להבין טוב טוב את ההשלכות... (דבר פשוט מאוד...)

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

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

                          @nigun
                          https://github.com/gofiber/fiber/issues/185

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

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

                            מצאתי את מקור הבעיה
                            https://github.com/gofiber/fiber/blob/efe89d243de6d8cf964581f5832b4341e2baa427/utils.go#L128-L130
                            הפונקציה הנ"ל בשימוש רחב בקובץ context.go
                            וזה הרי כבר מתועד בתיעוד הרשמי של fasthttp שאסור להשתמש ב-ctx אחרי שה-handler חוזר. וכן בהערה כאן, ועיין עוד: https://github.com/valyala/fasthttp/issues/146

                            אם fiber לא היו מחפים על השימוש ב-byte array על ידי המרה בצורה לא בטוחה למחרוזת היה יותר קל למצוא את הבעיה.

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

                            אז הנה למדנו משהו על go

                            לפי דרכי למדנו שלא כדאי להשתמש ב-unsafe בלי להבין טוב טוב את ההשלכות... (דבר פשוט מאוד...)

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

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

                            • מנטור אישי בתכנות והמסתעף – להתקדם לשלב הבא!
                            • בכל נושא אפשר ליצור קשר dovid@tchumim.com
                            yossizY תגובה 1 תגובה אחרונה
                            0
                            • 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
                                          תגובה
                                          • תגובה כנושא
                                          התחברו כדי לפרסם תגובה
                                          • מהישן לחדש
                                          • מהחדש לישן
                                          • הכי הרבה הצבעות


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

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

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